import subprocess,json,time,pathlib,sys,os,threading
session,side,pid,phase=sys.argv[1:5]
root=pathlib.Path(__file__).parent
out=root/(side+'-'+str(int(time.time())))
out.mkdir()
def ab(*args):
 r=subprocess.run(['npx','--yes','agent-browser','--session',session,*args],text=True,capture_output=True)
 if r.returncode:raise RuntimeError(r.stderr+r.stdout)
 return r.stdout
def io():
 return dict((k,int(v)) for k,v in (line.split(':') for line in pathlib.Path('/proc/'+pid+'/io').read_text().splitlines()))
ab('eval', 'Object.assign(window.usageEvidence,{phase:'+json.dumps(phase)+',requests:[],scans:[],max:0}) && "ready"')
ab('record','start',str(out/'refresh.webm'),'--fps','15')
time.sleep(1)
before=io(); start=time.monotonic()
thread=None
if len(sys.argv)>5:
 thread=subprocess.Popen(['node','apps/server/src/bin.ts','thread','send',sys.argv[6],'Concurrent responsiveness probe','--json','--base-dir','.t3'],cwd=sys.argv[5],stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True)

threadResult={}
if thread is not None:
 def finishThread():
  stdout,stderr=thread.communicate(timeout=60)
  threadResult.update(exit=thread.returncode,elapsedMs=round((time.monotonic()-start)*1000),stdout=stdout.strip())
 watcher=threading.Thread(target=finishThread);watcher.start()
ab('find','role','button','click','--name','Refresh usage')
ab('wait','--fn','window.usageEvidence.scans.length >= 1')
after=io()
metrics=json.loads(ab('eval','({scans:window.usageEvidence.scans,maxHttpMs:window.usageEvidence.max,requests:window.usageEvidence.requests})'))
if thread is not None:
 watcher.join()
 metrics['threadCommand']=threadResult
metrics['processReadChars']=after['rchar']-before['rchar'];metrics['side']=side;metrics['phase']=phase
(out/'metrics.json').write_text(json.dumps(metrics,indent=2))
ab('screenshot',str(out/'summary-a.png'));time.sleep(.5);ab('screenshot',str(out/'summary-b.png'))
time.sleep(1);ab('record','stop')
print(str(out),json.dumps({k:v for k,v in metrics.items() if k!='requests'}),flush=True)
