"""Usage: python3 drive.py BASE_CHECKOUT HEAD_CHECKOUT
Keep seed.ts beside this driver. Install checkout dependencies with vp i first.
Runs real server processes, stops captured PIDs, then probes SQLite writes offline.
Only selected server lines go in public transcripts; raw logs may contain secrets.
"""
import sys
import urllib.error
import pathlib, subprocess, os, sqlite3, time, socket, urllib.request, datetime, re, json, shutil
ROOT=pathlib.Path(__file__).resolve().parent
OUT=ROOT/datetime.datetime.now(datetime.timezone.utc).strftime('run-%Y%m%dT%H%M%S')
OUT.mkdir()
results={}
for label, side, checkout in [(label, side, pathlib.Path(sys.argv[1] if side=='before' else sys.argv[2]).resolve()) for label in ['existing-malformed', 'post-upgrade-writes', 'repair-existing-index'] for side in ['before','after']]:
    home=OUT/(label+'-'+side); (home/'userdata').mkdir(parents=True)
    db=home/'userdata/statev2.sqlite'; cwd=checkout/'apps/server'
    sha=subprocess.check_output(['git','rev-parse','HEAD'],cwd=checkout,text=True).strip()
    seed=cwd/'evidence-seed.ts'; shutil.copyfile(ROOT/'seed.ts',seed)
    try:
        seeded=subprocess.run(['node',str(seed),str(db),label],cwd=cwd,text=True,capture_output=True,check=True)
    finally: seed.unlink()
    with socket.socket() as s: s.bind(('127.0.0.1',0)); port=s.getsockname()[1]
    env=os.environ.copy(); env['T3CODE_DEV_SEED']='0'
    log=home/'raw-server.log'
    cmd=['node','src/bin.ts','serve','--base-dir',str(home),'--host','127.0.0.1','--port',str(port),'--no-browser']
    response=None
    with log.open('w') as f:
        p=subprocess.Popen(cmd,cwd=cwd,env=env,stdout=f,stderr=subprocess.STDOUT)
        try:
            deadline=time.monotonic()+75
            while time.monotonic()<deadline and p.poll() is None:
                try:
                    if 'Listening on http://' not in log.read_text():
                        time.sleep(.25)
                        continue
                    with urllib.request.urlopen(f'http://127.0.0.1:{port}/',timeout=1) as r:
                        response=f'HTTP {r.status}; content-type: {r.headers.get("Content-Type")}'
                        break
                except urllib.error.HTTPError as e:
                    response=f'HTTP {e.code}; server listening; web bundle not built for server-only reproduction'
                    break
                except Exception: time.sleep(.25)
            rc=p.poll()
        finally:
            if p.poll() is None:
                p.terminate()
                try:p.wait(timeout=15)
                except subprocess.TimeoutExpired:p.kill();p.wait()
    con=sqlite3.connect(db)
    version=con.execute('select max(migration_id) from effect_sql_migrations').fetchone()[0]
    rows=con.execute("select turn_item_id, payload_json from orchestration_v2_projection_turn_items").fetchall()
    writes=[]
    for sql in ["INSERT INTO orchestration_v2_projection_turn_items (turn_item_id,thread_id,run_id,ordinal,type,status,updated_at,payload_json) VALUES ('after-start','thread-1','run-1',2,'user_message','completed','2026-11-14T00:00:00.000Z','{not json')", "UPDATE orchestration_v2_projection_turn_items SET payload_json='still not json' WHERE turn_item_id='before-86'"]:
        try: con.execute(sql); con.commit(); writes.append('accepted')
        except Exception as e: writes.append(str(e));con.rollback()
    con.close()
    raw=log.read_text()
    selected=[]
    for line in raw.splitlines():
        if any(x in line for x in ['migration: 86_', 'migration: 92_', 'Listening on http://', 'MigrationError:', 'malformed JSON']):
            selected.append(re.sub(r'127\.0\.0\.1:\d+', '127.0.0.1:<port>', re.sub(r'\x1b\[[0-9;]*m','',line)))
    text='\n'.join([f'{side.upper()} — real T3 Code server — {label}',f'Commit: {sha}', 'Environment: Linux; Node '+subprocess.check_output(['node','--version'],text=True).strip(), 'Fresh synthetic database; T3CODE_DEV_SEED=0', 'Seed: runMigrations(toMigrationInclusive: ' + ('91); recreate original unguarded index' if label=='repair-existing-index' else '85)'), "Seed user_message payload_json = " + ("'{not json'" if label=="existing-malformed" else "'{}'"), 'Command: node src/bin.ts serve --base-dir <isolated-home> --host 127.0.0.1 --port <port> --no-browser','', 'Captured server output:',*selected,'',f'Server response: {response or "none; process exited"}',f'Server state before cleanup: {"running" if rc is None else "exited "+str(rc)}',f'Database migration after startup: {version}',f'Original row preserved: {rows}', f'Offline post-start malformed INSERT: {writes[0]}',f'Offline post-start malformed UPDATE: {writes[1]}',''])
    (OUT/f'{label}-{side}.txt').write_text(text)
    results[label+'-'+side]={'sha':sha,'version':version,'response':response,'exit':rc,'writes':writes}
    print(text,flush=True)
(OUT/'results.json').write_text(json.dumps(results,indent=2))
print('OUTPUT',OUT)
