import asyncio,sys,json
from pathlib import Path
sys.path.insert(0,str(Path.cwd()/'server'))
from device_gateway.control.projects import ProjectRegistry
from device_gateway.control.models import Settings
from device_gateway.control.pi import PiAdapter
from device_gateway.control.user_input import UserInputs
from device_gateway.integrations.pi import PiSessionRegistry
async def main():
 p=ProjectRegistry('.cache/native-probe/projects.json');project=p.get('probe');u=UserInputs();pi=PiAdapter(p,PiSessionRegistry(),user_inputs=u)
 try:
  models=await pi.creation_models(project);m=next((m for m in models if m.get('is_default')),models[0]);print('Pi native default',m['id'],flush=True)
  result=await pi.create_session(project,'Reply exactly PI_NATIVE_OK. Do not run tools.',Settings(model=m['id']),lambda sid:None,operation_id='native-pi-proof')
  sid=result['session_id'];print('Pi native create accepted',sid,flush=True)
  for _ in range(120):
   session=await pi.get_session(sid)
   outcome=await pi.rpc.call('smoke_result',{'session_id':sid})
   if outcome.get('stop_reason') and outcome['state']!='RUNNING':break
   await asyncio.sleep(.5)
  print('Pi native result',outcome,flush=True);assert outcome.get('stop_reason') not in ('error','aborted') and 'PI_NATIVE_OK' in outcome['text']
  settings=await pi.get_settings(sid);print('Pi model/effort/native readback',settings['model'],settings['effort'],settings['available_efforts'],flush=True)
  if settings['available_efforts']:
   chosen=settings['available_efforts'][0]
   updated=await pi.update_settings(sid,Settings(effort=chosen));assert updated['effort']==chosen
  ext=Path(project.path)/'.pi/extensions';ext.mkdir(parents=True,exist_ok=True)
  (ext/'native-ui-probe.ts').write_text('''export default function(pi) {
    pi.registerTool({name:'navigator_native_ui_probe',label:'Native UI probe',description:'Test official Pi confirm/select/input/editor dialogs once.',parameters:{type:'object',properties:{}},execute:async(_id,_params,_signal,_update,ctx)=>{
      const confirmed=await ctx.ui.confirm('Native two choices','Choose Yes or No');
      const selected=await ctx.ui.select('Native N choices',['One','Two','Three']);
      const input=await ctx.ui.input('Native free text');
      const editor=await ctx.ui.editor('Native editor','Initial text');
      return {content:[{type:'text',text:JSON.stringify({confirmed,selected,input,editor})}]};
    }});
  }''')
  result=await pi.create_session(project,'Call navigator_native_ui_probe exactly once, wait for each actual UI answer, then reply PI_NATIVE_UI_DONE. Do not run other tools.',Settings(model=m['id']),lambda sid:None,operation_id='native-pi-ui-proof')
  sid=result['session_id'];answers=0
  for _ in range(240):
   for e in u.pending():
    q=e['questions'][e['index']];wire=u.wire(e);print('REAL Pi UI',wire,flush=True)
    u.presentations['probe']=(e['request_id'],q['id']);answer=(q.get('options') or [{'label':'Native free answer'}])[0]['label']
    assert u.resolve('probe',e['request_id'],q['id'],answer);answers+=1
   outcome=await pi.rpc.call('smoke_result',{'session_id':sid})
   if outcome.get('stop_reason') and outcome['state']!='RUNNING' and not u.pending() and 'PI_NATIVE_UI_DONE' in outcome['text']:break
   await asyncio.sleep(.5)
  print('Pi UI outcome',answers,outcome,flush=True);assert answers==4 and 'PI_NATIVE_UI_DONE' in outcome['text'];print('Pi native confirm/select/input/editor PASS',flush=True)
 finally:await pi.close()
asyncio.run(main())
