import os, sys, json, base64, pathlib, subprocess, urllib.request, urllib.error
scratch = pathlib.Path(os.environ['PROOF_SCRATCH'])
home = pathlib.Path(sys.argv[1])
checkout = pathlib.Path(sys.argv[2])
origin = os.environ['PROOF_FORGEJO_URL']
user = os.environ['PROOF_FORGEJO_USER']
password = os.environ['PROOF_FORGEJO_PASSWORD']
auth = 'Basic ' + base64.b64encode(f'{user}:{password}'.encode()).decode()
def api(path, method='GET', body=None):
    req = urllib.request.Request(f'{origin}/api/v1/{path}', method=method, headers={'Authorization':auth,'Content-Type':'application/json'},data=None if body is None else json.dumps(body).encode())
    with urllib.request.urlopen(req) as r:
        return json.loads(r.read()) if r.status != 204 else None
repo = 'fast-forward-demo'
try: api(f'repos/{user}/{repo}', 'DELETE')
except urllib.error.HTTPError as e:
    if e.code != 404: raise
api('user/repos', 'POST', {'name':repo,'default_branch':'main','auto_init':True,'private':False})
api(f'repos/{user}/{repo}', 'PATCH', {'allow_merge_commits':False,'allow_squash_merge':False,'allow_rebase':False,'allow_rebase_explicit':False,'allow_fast_forward_only_merge':True})
workspace = home / 'workspaces' / 'Fast-forward demo'
workspace.mkdir(parents=True)
env = dict(os.environ, GIT_AUTHOR_NAME='Scenario', GIT_AUTHOR_EMAIL='scenario@example.invalid', GIT_COMMITTER_NAME='Scenario',GIT_COMMITTER_EMAIL='scenario@example.invalid',GIT_AUTHOR_DATE='2026-11-12T12:00:00Z',GIT_COMMITTER_DATE='2026-11-12T12:00:00Z')
def git(*args):
    return subprocess.check_output(['git',*args],cwd=workspace,env=env,text=True).strip()
git('init','-q','--initial-branch=main')
(workspace/'README.md').write_text('# Fast-forward merge demo\n')
git('add','.'); git('commit','-qm','Initial commit')
git('remote','add','origin',f'{origin}/{user}/{repo}.git')
git('-c',f'http.extraHeader=Authorization: {auth}','push','--force','-u','origin','main')
git('checkout','-qb','feature')
(workspace/'feature.txt').write_text('A fast-forward merge preserves the existing head commit.\n')
git('add','.');git('commit','-qm','Add fast-forward feature')
git('-c',f'http.extraHeader=Authorization: {auth}','push','-u','origin','feature')
pr=api(f'repos/{user}/{repo}/pulls','POST',{'title':'Fast-forward only: preserve the existing head','head':'feature','base':'main','body':'This repository allows only fast-forward merges. The feature branch contains main.'})
# The real tea CLI sends every request. This shim records only merge bodies, never credentials.
shim = home/'bin'/'tea'
shim.write_text('''#!/usr/bin/env python3
import os,sys,subprocess,json
from pathlib import Path
scratch=Path(__file__).resolve().parents[2]
env=dict(os.environ,XDG_CONFIG_HOME=str(scratch/'config'))
args=sys.argv[1:]
data=sys.stdin.buffer.read() if '@-' in args else None
if data and any('/merge' in a for a in args):
    with (scratch/'merge-requests.jsonl').open('a') as f: f.write(json.dumps(json.loads(data))+'\\n')
raise SystemExit(subprocess.run([str(scratch/'tea'),*args],env=env,input=data).returncode)
''')
shim.chmod(0o755)
subprocess.run(['node','apps/server/src/bin.ts','project','add',str(workspace),'--title','Fast-forward demo','--base-dir',str(home)],cwd=checkout,check=True,env=os.environ)
result={'repository':f'{user}/{repo}','pr':pr['number'],'url':pr['html_url'],'head':git('rev-parse','HEAD'),'base':git('rev-parse','main')}
(home/'fixture.json').write_text(json.dumps(result,indent=2))
print(json.dumps(result))
