from ops import *
image=json.loads((HERE/'image.json').read_text())
assert inspect('contextra-analytics-1')['Image']==image['id']
assert json.loads((HERE/'pose-fire-result.json').read_text())['pass_']
assert json.loads((HERE/'pose-fire-crowd-result.json').read_text())['pass_']
source=json.loads((PRIVATE/'selected-source.json').read_text());sid=source['stream_id']
before=json.loads((PRIVATE/'pose-before.json').read_text())
after=api('/api/v1/streams/'+sid+'/settings')['configured']
assert after==before,'Temporary settings not restored'
rows=api('/api/v1/streams')['streams']
assert all(r['state']=='stopped' and not r.get('child_pid') and not r.get('cleanup_pending') for r in rows)
save('gateway-resume-intent.json',dict(image=image,channels_stopped=len(rows)))
cmd(['docker','start','contextra-ai-gateway-1'],timeout=20)
cmd(['docker','exec','contextra-ai-gateway-1','nginx','-t','-c','/tmp/nginx.conf'],timeout=10)
code='''import urllib.request,json,os
from pathlib import Path
r=urllib.request.Request("http://localhost:8080/internal/bridge-status",headers={"Authorization":"Bearer "+Path(os.environ["CONTEXTRA_CONTROL_TOKEN_FILE"]).read_text().strip()})
print(json.dumps(json.load(urllib.request.urlopen(r,timeout=3))))'''
deadline=time.monotonic()+45
while True:
    bridge=json.loads(cmd(['docker','exec','contextra-ai-control-sidecar-1','python3','-B','-c',code],timeout=6))
    if bridge['wss']['connected'] or time.monotonic()>deadline:break
    time.sleep(3)
rows=api('/api/v1/streams')['streams']
baseline=json.loads((HERE/'baseline.json').read_text())
preserved=True
for name,old in baseline['containers'].items():
    if name in ('contextra-analytics-1','contextra-ai-gateway-1'):continue
    c=inspect(name)
    preserved=preserved and c['Id']==old['id'] and c['Image']==old['image'] and c['State']['StartedAt']==old['StartedAt']
assert preserved
models=json.loads(cmd(['docker','exec','contextra-analytics-1','python3','-B','-c',
 'import urllib.request,json;print(json.dumps({m:urllib.request.urlopen("http://127.0.0.1:8000/v2/models/"+m+"/ready",timeout=3).status for m in ["RFDETRMedium","RFDETRKeypointPreview","RFDETRFireSmoke","Awiros_person_and_head_detection"]}))']))
a=api('/api/v1/metadata/status')['artifacts']
env=dict(x.split('=',1) for x in inspect('contextra-analytics-1')['Config']['Env'])
policy={k:env[k] for k in ('CONTEXTRA_SINGLE_DECODE_MULTIPROVIDER','CONTEXTRA_CHANNEL_PROCESS_LIMIT','CONTEXTRA_PROVIDER_RESULT_FRESHNESS_MS','CONTEXTRA_PROVIDER_STALL_SECONDS')}
sql="SELECT json_build_object('artifact_state',artifact_state,'delivery_state',delivery_state,'http_status',http_status,'count',count(*),'max_attempts',max(attempts)) FROM contextra_event_artifacts WHERE created_at >= to_timestamp("+str((HERE/'baseline.json').stat().st_mtime)+") GROUP BY artifact_state,delivery_state,http_status;"
events=[json.loads(x) for x in cmd(['docker','exec','-i','contextra-postgresql-1','sh','-c',
 'exec psql -X -qAt -U "$POSTGRES_USER" -d "$POSTGRES_DB"'],input=sql).splitlines()]
final=dict(image=image,models=models,policy=policy,bridge=bridge,artifact={k:a[k] for k in ('enabled','http_enabled')},
    stopped=sum(r['state']=='stopped' and not r.get('child_pid') and not r.get('cleanup_pending') for r in rows),channels=len(rows),
    non_stopped=[{k:r.get(k) for k in ('stream_id','state','child_pid','cleanup_pending')} for r in rows if r['state']!='stopped' or r.get('child_pid') or r.get('cleanup_pending')],
    settings_exact_restored=True,non_target_preserved=preserved,ledger=ledger(),new_event_summary=events,
    root_free_gib=round(shutil.disk_usage('/').free/1024**3,2),web_schema='USER_REPORT_ONLY',web_browser='NOT_RUN')
save('final-state.json',final)
print(json.dumps(final))
