#!/usr/bin/env python3
"""Explicit real-model smoke; creates only a dedicated temporary project/session."""
import asyncio,json,os,pathlib,sys,time,tempfile,socket
REPO=pathlib.Path(__file__).resolve().parents[1]
import httpx
sys.path.insert(0,str(REPO/'server'))
from device_gateway.control.pi import PiAdapter
from device_gateway.control.projects import ProjectRegistry
from device_gateway.integrations.pi import PiSessionRegistry
ROOT=pathlib.Path(tempfile.mkdtemp(prefix='device-control-proof-')); CWD=ROOT/'pi-project';CWD.mkdir()
with socket.socket() as port_socket:
 port_socket.bind(('127.0.0.1',0)); PORT=port_socket.getsockname()[1]
print('Proof directory:', ROOT, flush=True)
async def main():
 env=os.environ.copy(); env.update(GATEWAY_PORT=str(PORT),GATEWAY_PROJECTS_FILE=str(ROOT/'pi-projects.json'),GATEWAY_STATE_FILE=str(ROOT/'targets.json'),DEVICE_LAB_CONTROL_DIR=str(ROOT/'pi-runtime'),GATEWAY_CODEX_ENABLED='0')
 os.environ.update({k:v for k,v in env.items() if k.startswith(('GATEWAY_','DEVICE_LAB_'))})
 host=PiAdapter(ProjectRegistry(ROOT/'pi-projects.json'),PiSessionRegistry())
 gateway=None; result={}
 async with httpx.AsyncClient(base_url=f'http://127.0.0.1:{PORT}',timeout=60) as client:
  async def start_gateway():
   p=await asyncio.create_subprocess_exec(str(REPO/'scripts/run-server.sh'),env=env,stdout=open(ROOT/'pi-gateway.log','a'),stderr=-2)
   for _ in range(100):
    try:
     if (await client.get('/health')).status_code==200:return p
    except httpx.ConnectError: pass
    await asyncio.sleep(.1)
   raise RuntimeError('Gateway failed to start')
  async def wait_text(sid,text):
   for _ in range(160):
    r=(await client.get('/api/status')).json()
    s=next((s for s in r['pi_sessions'] if s['session_id']==sid),{})
    if text in s.get('recent_text','') and s.get('state')=='DONE': return s
    if s.get('state')=='FAILED':raise RuntimeError('Pi run failed')
    await asyncio.sleep(1)
   raise TimeoutError('Pi output not observed: '+text)
  try:
   gateway=await start_gateway()
   if not (ROOT/'pi-projects.json').exists():
    response=await client.post('/api/projects',json={'id':'device-lab-control-smoke','name':'Pi control smoke','path':str(CWD)});response.raise_for_status()
   sid=(await host.rpc.call('create_smoke',{'cwd':str(CWD)}))['session_id'];result['session_id']=sid;print('created',sid,flush=True)
   r=await host.rpc.call('input',{'cwd':str(CWD),'session_id':sid,'text':'Reply exactly SESSION_READY'}); print('first submit',r,flush=True)
   await wait_text(sid,'SESSION_READY');result['first']='SESSION_READY';print('SESSION_READY observed',flush=True)
   await host.close();print('initial SDK process closed',flush=True)
   listing=(await client.get('/api/projects/device-lab-control-smoke/sessions')).json();print('catalog',listing,flush=True)
   session=next(s for s in listing['sessions'] if s['session_id']==sid);assert session['state']=='DORMANT';result['dormant']=True
   t=time.monotonic();r=await client.post(f'/api/agents/pi/sessions/{sid}/input',json={'text':'Reply exactly SESSION_RESUMED'});r.raise_for_status(); result['input']=r.json();result['http_seconds']=round(time.monotonic()-t,3);print('resume response',result['input'],flush=True)
   assert result['input']['resumed'] and result['input']['session_id']==sid
   await wait_text(sid,'SESSION_RESUMED');result['resumed_output']='SESSION_RESUMED';print('SESSION_RESUMED observed',flush=True)
   r=await client.post(f'/api/agents/pi/sessions/{sid}/input',json={'text':'Reply exactly SESSION_LIVE'});r.raise_for_status();assert not r.json()['resumed'];await wait_text(sid,'SESSION_LIVE');result['live_input']=True
   gateway.terminate();await gateway.wait();gateway=await start_gateway()
   listing=(await client.get('/api/projects/device-lab-control-smoke/sessions')).json();session=next(s for s in listing['sessions'] if s['session_id']==sid);assert session['state']=='DORMANT';result['restart_rediscovery']=True
  except Exception as e: result['error']=str(e);print('ERROR',e,flush=True)
  finally:
   await host.close()
   if gateway and gateway.returncode is None:gateway.terminate();await gateway.wait()
   (ROOT/'pi-result.json').write_text(json.dumps(result,indent=2));print(json.dumps(result,indent=2),flush=True)
   if 'error' in result: raise SystemExit(1)
if __name__ == '__main__':
 asyncio.run(main())
