#!/usr/bin/env python3
"""Run the issue reproduction against a checkout's real T3 server.
Usage: python3 reproduce.py CHECKOUT OUTPUT_PARENT SIDE PORT
Each run creates fresh synthetic repositories and a fresh T3 home.
Only filtered public response fields are written; bearer tokens stay in memory.
"""
import datetime, json, os, pathlib, subprocess, sys, threading, time, urllib.request

checkout, parent, side, port = sys.argv[1:]
root = pathlib.Path(parent) / (side + '-' + datetime.datetime.now(datetime.timezone.utc).strftime('%Y%m%dT%H%M%S%fZ'))
root.mkdir(parents=True)
home = root / 'home'
env = {**os.environ, 'T3CODE_DEV_SEED': '0', 'GIT_CONFIG_GLOBAL': '/dev/null'}

def run(args, cwd=checkout):
    result = subprocess.run(args, cwd=cwd, env=env, text=True, capture_output=True, check=True)
    return result.stdout.strip()

sha = run(['git', 'rev-parse', 'HEAD'])
remotes = {'app': 'ssh://git@git.example.test/team repos/app.git', 'control': 'ssh://git@git.example.test/team-repos/control.git'}
for title, remote in remotes.items():
    repo = root / title
    repo.mkdir()
    run(['git', 'init', '--quiet', '--initial-branch=main'], repo)
    (repo / 'README.md').write_text('Synthetic repository for repository identity reproduction.\n')
    run(['git', 'add', 'README.md'], repo)
    run(['git', '-c', 'user.name=Reproduction', '-c', 'user.email=reproduction@example.invalid', 'commit', '--quiet', '-m', 'Initial commit'], repo)
    run(['git', 'remote', 'add', 'origin', remote], repo)

cli = ['node', 'apps/server/src/bin.ts']
server = subprocess.Popen(cli + ['serve', '--base-dir', str(home), '--host', '127.0.0.1', '--port', port], cwd=checkout, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
# Drain startup diagnostics without persisting pairing credentials or runtime metadata.
threading.Thread(target=lambda: list(server.stdout), daemon=True).start()
origin = 'http://127.0.0.1:' + port
try:
    deadline = time.monotonic() + 90
    while True:
        try:
            urllib.request.urlopen(origin + '/.well-known/t3/environment', timeout=2).read()
            break
        except Exception:
            if server.poll() is not None:
                raise RuntimeError('Server exited before readiness')
            if time.monotonic() > deadline:
                raise RuntimeError('Server did not become ready')
            time.sleep(.25)
    for title in remotes:
        run(cli + ['project', 'add', str(root / title), '--title', title, '--base-dir', str(home)])
    token = run(cli + ['auth', 'session', 'issue', '--token-only', '--base-dir', str(home)])
    request = urllib.request.Request(origin + '/api/orchestration/shell', headers={'Authorization': 'Bearer ' + token, 'x-t3-orchestration-protocol': '2'})
    # The shell endpoint first returns cached enrichment and starts background git probes.
    # Wait for the dash-separated control's identity before capturing either side.
    deadline = time.monotonic() + 90
    while True:
        with urllib.request.urlopen(request) as response:
            status = response.status
            shell = json.load(response)
        projects = sorted([{'title': p['title'], 'identity': (p.get('repositoryIdentity') or {}).get('locator', {}).get('remoteUrl')} for p in shell['projects'] if p['title'] in remotes], key=lambda p:p['title'])
        if any(p['title'] == 'control' and p['identity'] == remotes['control'] for p in projects):
            break
        if time.monotonic() > deadline:
            raise RuntimeError('Control identity did not become available')
        time.sleep(.5)
    if len(projects) != 2:
        raise RuntimeError('Expected two synthetic projects')
    transcript = f'''Issue 35034 — {side.upper()}
Commit: {sha}
Environment: Linux; real Node T3 server; loopback HTTP
Fresh database; T3CODE_DEV_SEED=0; GIT_CONFIG_GLOBAL=/dev/null

1. Create and commit two synthetic git repositories.
2. Set origin URLs:
   app:     {remotes['app']}
   control: {remotes['control']}
3. Start: node apps/server/src/bin.ts serve --base-dir <fresh-home>
4. Add each repository: t3 project add <repo> --title <title>
5. Issue a bearer session with t3 auth session issue --token-only.
6. GET /api/orchestration/shell
   Authorization: Bearer <redacted>
   x-t3-orchestration-protocol: 2
   HTTP {status}
7. Wait for control repository enrichment, then select projects: {{title, identity: .repositoryIdentity.locator.remoteUrl}}

ACTUAL SERVER RESPONSE (filtered to synthetic project fields):
{json.dumps(projects, indent=2)}
'''
    (root / 'transcript.txt').write_text(transcript)
    (root / 'response.json').write_text(json.dumps({'commit':sha,'httpStatus':status,'projects':projects}, indent=2) + '\n')
    print(transcript)
    print('CAPTURE_DIRECTORY=' + str(root))
finally:
    server.terminate()
    try:
        server.wait(timeout=20)
    except subprocess.TimeoutExpired:
        server.kill()
        server.wait()
