#!/usr/bin/env python3
"""Prepare isolated Copilot ACP evidence, discovering model IDs without publishing them.
Usage: prepare-proof.py ROOT SIDE WORKTREE COPILOT_BINARY [--stored-default]
Keep ROOT private. Run separately for base and head. See reproduction.md.
"""
import json, os, pathlib, shutil, subprocess, sys
root, side, checkout, binary = sys.argv[1:5]
root, checkout = pathlib.Path(root).resolve(), pathlib.Path(checkout).resolve()
home = root / side / 'copilot-home'
home.mkdir(parents=True, exist_ok=True)
private = root / 'private-selection.json'
if not private.exists():
    probe_home = root / 'discovery-home'
    probe_home.mkdir(exist_ok=True)
    env = dict(os.environ, COPILOT_HOME=str(probe_home), GH_TOKEN=subprocess.check_output(['gh','auth','token'], text=True).strip())
    p = subprocess.Popen([binary, '--acp'], env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True)
    def call(i, method, params):
        p.stdin.write(json.dumps(dict(jsonrpc='2.0', id=i, method=method, params=params))+'\n')
        p.stdin.flush()
        while True:
            reply = json.loads(p.stdout.readline())
            if reply.get('id') == i:
                if 'error' in reply: raise RuntimeError(reply['error'])
                return reply['result']
    try:
        call(1, 'initialize', dict(protocolVersion=1, clientCapabilities={}, clientInfo=dict(name='proof',version='1')))
        session = call(2, 'session/new', dict(cwd=str(root),mcpServers=[]))
    finally:
        p.terminate(); p.wait()
    models = next(c for c in session['configOptions'] if c['id']=='model')
    a = models['currentValue']
    options = models['options']
    # The next listed concrete model after the advertised default supported reasoning in this run.
    b = options[next(i for i,m in enumerate(options) if m['value']==a)+1]['value']
    aliases = {}
    for i,m in enumerate(options):
        label = 'Model A' if m['value']==a else 'Model B' if m['value']==b else f'Alternative {i}'
        aliases[m['value']] = label
        aliases[m['name']] = label
    (root/'private-aliases.json').write_text(json.dumps(aliases))
    private.write_text(json.dumps(dict(a=a,b=b)))
selection = json.loads(private.read_text())
if '--stored-default' in sys.argv:
    (home/'settings.json').write_text(json.dumps({'model':selection['b']}))
    print('Stored default set to Model B; no identifiers printed.')
    sys.exit()
(home/'settings.json').write_text(json.dumps({'model':selection['a']}))
bindir = root/side/'bin'
bindir.mkdir(parents=True,exist_ok=True)
wrapper = bindir/'copilot'
shutil.copyfile(pathlib.Path(__file__).with_name('copilot-wrapper.py'),wrapper)
wrapper.chmod(0o755)
# The wrapper uses this symlink, retaining the installed CLI version.
target = root/'copilot/node_modules/.bin/copilot'
target.parent.mkdir(parents=True,exist_ok=True)
if not target.exists(): target.symlink_to(pathlib.Path(binary).resolve())
settings = {'defaultModelSelection':{'instanceId':'copilotProof','model':selection['a']}, 'providerInstances':{k:{'driver':k,'enabled':False} for k in ['codex','claudeAgent','cursor','grok','muse','pi','opencode','antigravity']}}
settings['providerInstances']['copilotProof'] = {'driver':'acpRegistry','displayName':'Copilot','enabled':True,'config':{'source':'local','commandPath':str(wrapper),'commandArgs':['--acp']}}
t3 = checkout/'.t3/userdata'
t3.mkdir(parents=True,exist_ok=True)
(t3/'settings.json').write_text(json.dumps(settings))
print('Prepared isolated provider; model identifiers remain in private scratch files.')
