from ops import *
import yaml
PRIVATE.chmod(0o700);HERE.chmod(0o700)
rows=api('/api/v1/streams')['streams']
mapping={s['stream_id']:s.get('camera_id',s.get('source_id')) for s in yaml.safe_load(Path('/data/contextra/runtime-state/streams_runtime.yaml').read_text())['added']}
baseline={}
for n in cmd(['docker','ps','-a','--format','{{.Names}}']).splitlines():
    c=inspect(n);baseline[n]=dict(id=c['Id'],image=c['Image'],started=c['State']['StartedAt'],running=c['State']['Running'])
targets=[dict(stream_id=r['stream_id'],camera=mapping.get(r['stream_id'])) for r in rows if r['state']=='running']
save('baseline.json',dict(containers=baseline,targets=targets,ledger=ledger()))
save('compose-before.json',json.loads(cmd(compose()+['config','--format','json'])),private=True)
save('settings-before.json',{r['stream_id']:api('/api/v1/streams/'+r['stream_id']+'/settings')['configured'] for r in targets},private=True)
shutil.copyfile('/workspace/contextra-runtime-config/web-start-candidate-20260918/candidate.env',PRIVATE/'candidate.env.before')
cmd(['docker','stop','--signal=SIGTERM','--timeout=-1','contextra-ai-gateway-1'],timeout=90)
for r in rows:
    if r['state']!='stopped' or r.get('child_pid') or r.get('cleanup_pending'):
        request('/api/v1/streams/'+r['stream_id']+'/stop',{},timeout=90)
deadline=time.monotonic()+25
while True:
    after=api('/api/v1/streams')['streams']
    if all(r['state']=='stopped' and not r.get('child_pid') and not r.get('cleanup_pending') for r in after):break
    if time.monotonic()>deadline:raise RuntimeError('STOP_REAP_FAILED')
    time.sleep(1)
save('maintenance.json',dict(stopped=len(after),cameras=[t['camera'] for t in targets]))
print(json.dumps(dict(stopped=len(after),test_cameras=[t['camera'] for t in targets])))
