import datetime,json,pathlib,sqlite3,sys,time
# Read-only observer: never sends a turn or changes the running app.
base,head,base_ws,head_ws,out=sys.argv[1:]
with open(out,'a',buffering=1) as log:
 for sample in range(43):
  result={'observedAt':datetime.datetime.now(datetime.timezone.utc).isoformat()}
  for side,root,workspace in [('before',base,base_ws),('after',head,head_ws)]:
   db=sqlite3.connect('file:'+str(pathlib.Path(root)/'.t3/userdata/statev2.sqlite')+'?mode=ro',uri=True)
   sessions=db.execute("select status,updated_at from orchestration_v2_projection_provider_sessions where json_extract(payload_json,'$.cwd')=?",(workspace,)).fetchall()
   tools=[]
   for (raw,) in db.execute("select payload_json from orchestration_v2_projection_turn_items where type='dynamic_tool' and thread_id in (select thread_id from orchestration_v2_projection_provider_sessions where json_extract(payload_json,'$.cwd')=?)",(workspace,)):
    p=json.loads(raw)
    if p.get('toolName') in ('CronCreate','CronList'):
     tools.append({k:p.get(k) for k in ('toolName','input','output','startedAt','completedAt','status')})
   events=db.execute("select event_type,occurred_at from orchestration_v2_events where event_type like '%session%' order by sequence").fetchall()
   f=pathlib.Path(workspace)/'cron-fired.txt'
   result[side]={'sessions':sessions,'cronTools':tools,'sessionEvents':events,'fileExists':f.exists(),'fileContent':f.read_text() if f.exists() else None}
   db.close()
  log.write(json.dumps(result)+'\n')
  print(result['observedAt'], 'before',result['before']['sessions'],result['before']['fileContent'],'after',result['after']['sessions'],result['after']['fileContent'],flush=True)
  time.sleep(60)
