#!/usr/bin/env python3
"""Run real T3 serve; record only allowlisted diagnostics (never pairing credentials)."""
import os, sys, pathlib, subprocess, time, selectors, json, signal, datetime
root=pathlib.Path(__file__).parent
out=root/datetime.datetime.now(datetime.timezone.utc).strftime('run-%Y%m%d-%H%M%S');out.mkdir()
binpath=out/'bin';binpath.mkdir()
fake='''#!/usr/bin/python3
import os,sys,json,time
from pathlib import Path
args=sys.argv[1:]
if args[:1]==['status']:
 print(json.dumps({'Self':{'DNSName':'demo.example.ts.net.','TailscaleIPs':['100.64.0.10'],'CapMap':{'https':[]}}}))
elif args[:2]==['debug','prefs']: print('{"WantRunning":true,"RunSSH":false}')
elif args[:2]==['serve','status']: print('null')
elif args[:1]==['serve']:
 if 'off' in args: sys.exit(0)
 Path(os.environ['MARKER']).write_text(json.dumps({'args':args,'applied':True,'time':time.time()}))
 print('Available within your tailnet:')
 for i in range(int(os.environ['ROUTES'])):
  print('https://demo.example.ts.net/existing-project-dashboard-and-api-preview-environment-route-%04d -> http://127.0.0.1:23773 (proxy)' % i)
 print('Serve started and running in the background.')
 sys.stdout.flush()
 Path(os.environ['FINISHED']).write_text('exit 0')
else: print('{}')
'''
(binpath/'tailscale').write_text(fake);(binpath/'tailscale').chmod(0o755)
for side,checkout in [('before',sys.argv[1]),('after',sys.argv[2])]:
 for routes in [1,4000]:
  name=f'{side}-{routes}';events=[];start=time.monotonic()
  def emit(s):
   e=[round(time.monotonic()-start,3),s];events.append(e);print(name,*e,flush=True)
  sha=subprocess.check_output(['git','rev-parse','HEAD'],cwd=checkout,text=True).strip()
  emit('Real T3 CLI / Linux / fresh isolated state / synthetic Tailscale')
  emit('Commit '+sha)
  emit('$ t3 serve --tailscale-serve --host 127.0.0.1 --port 23773')
  emit(f'Fake tailscale: apply marker, print {routes} routes, exit 0')
  marker=out/(name+'-applied.json');finished=out/(name+'-finished')
  env={**os.environ,'PATH':str(binpath)+os.pathsep+os.environ['PATH'],'T3CODE_DEV_SEED':'0','MARKER':str(marker),'FINISHED':str(finished),'ROUTES':str(routes),'NO_COLOR':'1'}
  p=subprocess.Popen(['node','src/bin.ts','serve','--tailscale-serve','--host','127.0.0.1','--port','23773','--base-dir',str(out/(name+'-state'))],cwd=pathlib.Path(checkout)/'apps/server',env=env,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,start_new_session=True)
  sel=selectors.DefaultSelector();sel.register(p.stdout,selectors.EVENT_READ);buf=b'';raw=b'';seen=False;done=False
  try:
   while time.monotonic()-start<65 and p.poll() is None:
    if marker.exists() and not seen:emit('Fixture: mapping applied=true (marker exists)');seen=True
    for key,_ in sel.select(.1):
     chunk=os.read(key.fileobj.fileno(),65536);raw+=chunk;buf+=chunk
     while b'\n' in buf:
      line,buf=buf.split(b'\n',1);line=line.decode(errors='replace')
      if 'Tailscale Serve configured' in line:emit('T3 output: Tailscale Serve configured');done=True
      if 'Failed to configure Tailscale Serve' in line:emit('T3 output: Failed to configure Tailscale Serve');done=True
      if 'TailscaleCommandTimeoutError' in line:emit('T3 output: TailscaleCommandTimeoutError')
      if 'timeoutMs: 10000' in line:emit('T3 output: timeoutMs: 10000')
    if done:
     # Capture the rest of the same diagnostic block before stopping.
     if any('10000ms' in x[1] for x in events) or any('configured'==x[1].split()[-1] for x in events):break
     if events and time.monotonic()-start-events[-1][0]>1:break
   emit('Fixture: summary completed / exit 0 reached='+str(finished.exists()).lower())
   emit('Fixture: mapping applied='+str(marker.exists()).lower())
  finally:
   (out/(name+'-raw-private.log')).write_bytes(raw)
   if p.poll() is None: os.killpg(p.pid,signal.SIGTERM)
   try:p.wait(timeout=10)
   except subprocess.TimeoutExpired:os.killpg(p.pid,signal.SIGKILL);p.wait()
   sel.close()
  (out/(name+'-raw-private.log')).write_bytes(raw)
  (out/(name+'.json')).write_text(json.dumps(events,indent=2))
  (out/(name+'.txt')).write_text('\n'.join(f'[{t:06.3f}s] {s}' for t,s in events)+'\n')
print('OUTPUT',out)
