#!/usr/bin/env python3
"""Synthetic worktree proof fixture. Run prepare, start app with seed disabled, then seed/damage/inspect.
All output directories are supplied by the caller. No installed T3 state is read.
"""
import json, os, pathlib, subprocess, sys, datetime
operation, checkout_arg, output_arg = sys.argv[1:4]
checkout = pathlib.Path(checkout_arg).resolve()
out = pathlib.Path(output_arg).resolve()
home = out / 't3-home'
def run(args, cwd=checkout):
    return subprocess.run(args, cwd=cwd, check=True, capture_output=True, text=True).stdout
def cli(args):
    return run(['node','apps/server/src/bin.ts',*args,'--base-dir',str(home)])
if operation == 'prepare':
    out.mkdir(parents=True, exist_ok=False)
    repo = out / 'checkout-demo'
    files = {
        'package.json': json.dumps({'name':'checkout-demo','private':True,'dependencies':{'fixture-package':'file:./fixture-package'}}),
        'fixture-package/package.json':json.dumps({'name':'fixture-package','version':'1.0.0'}),
        '.gitignore':'node_modules/\n.next/\n',
        'README.md':'# Checkout restored\nThis file belongs to the tracked checkout.\n',
    }
    for name, data in files.items():
        file = repo/name
        file.parent.mkdir(parents=True,exist_ok=True)
        file.write_text(data)
    run(['git','init','--quiet','--initial-branch=main'], repo)
    run(['git','add','--all'],repo)
    run(['git','-c','user.name=Scenario','-c','user.email=scenario@example.invalid','commit','--quiet','-m','Initial commit'],repo)
    settings = {
        'defaultModelSelection': {'instanceId':'devReplay','model':'multi-turn'},
        'defaultProjectScripts':[{'id':'install','name':'Install dependencies','command':'pnpm install --ignore-scripts','icon':'configure','runOnWorktreeCreate':True}],
        'providerInstances':{driver:{'driver':driver,'enabled':False} for driver in ['codex','claudeAgent','cursor','grok','muse','pi','opencode','antigravity']},
    }
    (home/'userdata').mkdir(parents=True,exist_ok=True)
    (home/'userdata'/'settings.json').write_text(json.dumps(settings))
    shell = out/'proof-shell'
    shell.write_text('#!/bin/sh\nexport PS1="$ "\nunset PROMPT_COMMAND\nexec /bin/bash --noprofile --norc "$@"\n')
    shell.chmod(0o755)
    (out/'meta.json').write_text(json.dumps({'project':str(repo),'checkout':str(checkout),'home':str(home)}))
    print('Prepared synthetic pnpm project and isolated app settings.')
elif operation == 'seed':
    meta=json.loads((out/'meta.json').read_text())
    cli(['project','add',meta['project'],'--title','checkout-demo'])
    start=json.loads(cli(['thread','start',meta['project'],'Initialize the workspace','--title','Restore leftover checkout','--provider','devReplay','--model','multi-turn','--worktree','main','--branch','proof/restore-checkout','--wait','--json']))
    thread=json.loads(cli(['thread','show',start['threadId'],'--json']))['thread']
    meta.update(threadId=start['threadId'],folder=thread['worktreePath'])
    (out/'meta.json').write_text(json.dumps(meta))
    print(json.dumps({'threadId':meta['threadId'],'dependenciesInstalled':(pathlib.Path(meta['folder'])/'node_modules').is_dir(),'branch':thread['branch']}))
elif operation == 'cleanup-seed':
    meta=json.loads((out/'meta.json').read_text())
    start=json.loads(cli(['thread','start',meta['project'],'Initialize cleanup fixture','--title','Cleanup leftover checkout','--provider','devReplay','--model','multi-turn','--worktree','main','--branch','proof/cleanup-leftover','--wait','--json']))
    thread=json.loads(cli(['thread','show',start['threadId'],'--json']))['thread']
    meta.update(cleanupThreadId=start['threadId'],cleanupFolder=thread['worktreePath'])
    (out/'meta.json').write_text(json.dumps(meta))
    print(json.dumps({'cleanupThreadId':meta['cleanupThreadId'],'dependenciesInstalled':(pathlib.Path(meta['cleanupFolder'])/'node_modules').is_dir()}))
elif operation == 'cleanup-config':
    settings_path=home/'userdata/settings.json'
    settings=json.loads(settings_path.read_text())
    settings.setdefault('storageCleanup',{})['worktreeSettledAfterDays']=0
    settings_path.write_text(json.dumps(settings))
    print('Cleanup: settled worktrees eligible after zero days.')
elif operation in ['damage','cleanup-damage']:
    import shutil
    meta=json.loads((out/'meta.json').read_text())
    folder=pathlib.Path(meta['cleanupFolder'] if operation=='cleanup-damage' else meta['folder'])
    for entry in folder.iterdir():
        if entry.name!='node_modules':
            if entry.is_dir() and not entry.is_symlink(): shutil.rmtree(entry)
            else: entry.unlink()
    (folder/'.next').mkdir()
    if operation=='cleanup-damage':
        (folder/'node_modules'/'.proof-retained').write_text('Keep this dependency leftover.\n')
    run(['git','worktree','prune'],pathlib.Path(meta['project']))
    print(json.dumps({'remaining':sorted(x.name for x in folder.iterdir()),'gitExists':(folder/'.git').exists()}))
elif operation == 'inspect':
    meta=json.loads((out/'meta.json').read_text())
    folder=pathlib.Path(meta['folder'])
    branch=subprocess.run(['git','-C',str(folder),'branch','--show-current'],env={**os.environ,'GIT_CEILING_DIRECTORIES':str(folder.parent)},capture_output=True,text=True)
    print(json.dumps({'entries':sorted(x.name for x in folder.iterdir()),'gitExists':(folder/'.git').exists(),'readmeExists':(folder/'README.md').exists(),'branch':branch.stdout.strip(),'gitExit':branch.returncode,'gitError':branch.stderr.strip()}))
else: raise SystemExit('Unknown operation')
