from ops import *

source = json.loads((PRIVATE / 'selected-source.json').read_text())
sid = source['stream_id']
before = json.loads((PRIVATE / 'canary-settings-before.json').read_text())
current = api('/api/v1/streams/' + sid + '/settings')['configured']
assert not inspect('contextra-ai-gateway-1')['State']['Running']
assert all(r['state'] == 'stopped' and not r.get('child_pid') and not r.get('cleanup_pending')
           for r in api('/api/v1/streams')['streams'])
fields = ('intrusion', 'loitering', 'fall', 'fight', 'crowd', 'tracking', 'frame_time_anchor')
changes = {k: before[k] for k in fields if current[k] != before[k]}
if current['fire'] != before['fire']:
    changes['fire'] = before['fire']
    if 'scenario' not in before['fire']:
        changes['fire'] = dict(before['fire'], scenario={'enabled': False})
if not (HERE / 'cleanup-settings-intent.json').exists():
    save('cleanup-settings-intent.json', {'fields': sorted(changes), 'camera': 3})
if changes and not (PRIVATE / 'cleanup-settings-after.json').exists():
    request('/api/v1/streams/' + sid + '/settings',
            dict(expected_revision=current['revision'], **changes), method='PATCH')
after = api('/api/v1/streams/' + sid + '/settings')['configured']
assert all(after[k] == before[k] for k in fields)
assert after['fire']['enabled'] == before['fire']['enabled']
assert not after['fire'].get('scenario', {}).get('enabled', False)
if not (PRIVATE / 'cleanup-settings-after.json').exists():
    save('cleanup-settings-after.json', after, private=True)
baseline = json.loads((HERE / 'baseline.json').read_text())
rows = api('/api/v1/streams')['streams']
artifact = api('/api/v1/metadata/status')['artifacts']
containers = {}
for name, old in baseline['containers'].items():
    if name == 'contextra-pr13-web-target':
        continue  # This task's --rm CPU fixture, not a persistent service.
    c = inspect(name)
    containers[name] = dict(id=c['Id'], image=c['Image'], started=c['State']['StartedAt'],
                            running=c['State']['Running'])
others = [n for n in containers if n not in ('contextra-analytics-1', 'contextra-ai-gateway-1')]
preserved = all(all(containers[n][k] == baseline['containers'][n][k]
                    for k in ('id', 'image', 'started')) for n in others)
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"]}))']))
assert ledger() == baseline['ledger']
kernel = cmd(['dmesg', '--since', '2026-09-23 11:08:00', '--until', '2026-09-23 11:09:00'])
save('native-failure.json', {'kernel_evidence': kernel, 'cause': 'UNKNOWN',
    'observed': 'segmentation fault in libnvds_service_maker.so; batch_capture-m task'})
status = dict(stopped=len(rows), all_stopped=all(r['state']=='stopped' and not r.get('child_pid') and not r.get('cleanup_pending') for r in rows),
    image=containers['contextra-analytics-1']['image'], models=models,
    artifact={k:artifact[k] for k in ('enabled', 'http_enabled')}, ledger_unchanged=True,
    non_target_preserved=preserved, gateway='MAINTENANCE_STOPPED',
    camera3_original_settings_semantics_restored=True,
    retained_fire_defaults='disabled scenario materialized by CAS; no raw YAML overwrite',
    automatic_rollback=False, browser_ready=False,
    blocker='ServiceMaker native crash before first provider result',
    root_free_gib=round(shutil.disk_usage('/').free/1024**3, 2))
assert status['all_stopped']
save('final-state.json', status)
print(json.dumps(status))
