from ops import *
import yaml
rows=api('/api/v1/streams')['streams']
assert all(not r.get('child_pid') and not r.get('cleanup_pending') and
           all(not p.get('child_pid') for p in r.get('provider_processes',{}).values()) for r in rows)
save('pre-recovery.json',dict(channels=[{k:r.get(k) for k in ('stream_id','state','last_error','cleanup_error','last_cleanup')} for r in rows],
     image=inspect('contextra-analytics-1')['Image'],gpu=cmd(['nvidia-smi','--query-gpu=memory.used','--format=csv,noheader']).strip()))
deadline=time.monotonic()+70
while True:
    a=api('/api/v1/metadata/status')['artifacts']
    if not a.get('active') and not a.get('rendering'):break
    if time.monotonic()>deadline:raise RuntimeError('ARTIFACT_DRAIN_BOUND')
    time.sleep(1)
assert not inspect('contextra-ai-gateway-1')['State']['Running']
image=inspect('contextra-analytics-1')['Image']
cmd(['docker','stop','--signal=SIGTERM','--timeout=-1','contextra-analytics-1'],timeout=90)
assert inspect('contextra-analytics-1')['State']['ExitCode']==0
cmd(compose()+['up','-d','--no-deps','--no-build','--pull','never','analytics'],timeout=150)
deadline=time.monotonic()+120
while True:
    try:api('/ready');break
    except Exception:
        if time.monotonic()>deadline:raise RuntimeError('READY_BOUND')
        time.sleep(2)
assert inspect('contextra-analytics-1')['Image']==image
saved=json.loads((PRIVATE/'settings-original.json').read_text())
source=yaml.safe_load((PRIVATE/'runtime-original.yaml').read_text())['added']
item=next(s for s in source if str(s.get('camera_id'))=='14');sid=item['stream_id']
current=api('/api/v1/streams/'+sid+'/settings')['configured']
changes={k:saved['14'][k] for k in ('intrusion','loitering','fall','fight','fire','crowd','tracking')}
if 'scenario' not in changes['fire']:changes['fire']=dict(changes['fire'],scenario={'enabled':False})
request('/api/v1/streams/'+sid+'/settings',dict(expected_revision=current['revision'],**changes),method='PATCH')
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('recovery.json',dict(image=image,normal_exit=True,stopped=len(rows),camera_restart=False))
print(json.dumps(dict(recovered=True,stopped=len(rows),same_image=True)),flush=True)
