import importlib.util,json,os,shutil,urllib.request
from pathlib import Path
os.umask(0o077)
R=Path(__file__).parent
HEAD='05d525d1d9cfb6ceb44b3ae7fd8693e29b60e8db'
s=importlib.util.spec_from_file_location('gate','/tmp/codex/ltb1021/2026-09-11_service-stop_r01/gate.py')
g=importlib.util.module_from_spec(s);s.loader.exec_module(g)
def api(path):
    env=g.load_env_file(str(g.ENV))
    op=urllib.request.build_opener(urllib.request.ProxyHandler({}))
    with op.open('http://127.0.0.1:'+env['FASTAPI_HOST_PORT']+path,timeout=4) as response:return json.load(response)
if __name__=='__main__':
    assert not (R/'plan.json').exists()
    assert g.sh(['git','-C',str(g.REPO),'rev-parse','HEAD']).strip()==HEAD
    assert not g.sh(['git','-C',str(g.REPO),'status','--porcelain']).strip()
    c=g.inspect();env=g.load_env_file(str(g.ENV));active=g.ENV.parent/'metadata-active/compose.yaml'
    overlay=Path(env['CONTEXTRA_RUNTIME_STATE_ROOT'])/'streams_runtime.yaml'
    streams=api('/api/v1/streams')['streams'];assert all(x['state']=='stopped' for x in streams)
    old=json.loads(Path('/tmp/codex/ltb1021/2026-09-14_contextra-intrusion-preparation_r01/plan.json').read_text())
    root=g.sh(['docker','info','--format','{{.DockerRootDir}}']).strip();free=shutil.disk_usage(root).free;assert free>=15*1024**3
    addresses=json.loads(g.sh(['ip','-j','-4','address','show']))
    lan=[a for i in addresses if i['ifname']=='enp6s18' for a in i['addr_info'] if a['scope']=='global'];assert len(lan)==1
    registry=Path('/workspace/contextra-runtime-config/rtsp-test/registry.json')
    for name,path in [('env.before',g.ENV),('active-compose.before',active),('overlay.before',overlay),('registry.before',registry)]:shutil.copyfile(path,R/name)
    inp=Path('/tmp/codex/ltb1021/2026-09-14_contextra-rtsp-cli_r01/입력 샘플 #1, 특수문자.mp4')
    source=json.loads(Path('/tmp/codex/ltb1021/2026-09-14_contextra-rtsp-cli_r01/input.json').read_text())
    assert g.sha(inp)==source['derived_sha256'] and g.sha(Path(source['source']))==source['source_sha256']
    plan=dict(started_utc='2026-09-14T08:15:41Z',head=HEAD,analytics=c,other_containers=g.others(),streams=streams,
              env_hash=g.sha(g.ENV),active=str(active),active_hash=g.sha(active),overlay=str(overlay),overlay_hash=g.sha(overlay),
              registry=str(registry),registry_hash=g.sha(registry),normal_restart=c['HostConfig']['RestartPolicy'],
              docker_root=root,disk_free=free,gpu_mib=g.gpu(),lan=lan[0],short_input=str(inp),original_input=source,
              model_hashes={**old['pose_hashes'],str(g.CFG):old['config_hash'],str(g.CFG.parent/'2/model.plan'):old['plan_hash'],
               str(Path(old['fire_model']['directory'])/'config.pbtxt'):old['fire_model']['config_hash'],
               str(Path(old['fire_model']['directory'])/'2/model.plan'):old['fire_model']['plan_sha256']})
    assert all(g.sha(Path(p))==h for p,h in plan['model_hashes'].items())
    (R/'plan.json').write_text(json.dumps(plan,indent=2))
    (R/'ledger.json').write_text(json.dumps(dict(started=plan['started_utc'],sender_trials=[],api_trials=[],builds=[],reflection=0,
       limits=dict(preparation_minutes=20,runtime_minutes=35,same_failure_stop=2,sender_seconds=60,receiver_seconds=20,
       sender_cpu=1,sender_ram_mib=512,receiver_cpu=1,receiver_ram_mib=512,gpu_devices=0,log_bytes=1048576)),indent=2))
    print(json.dumps(dict(stopped=True,healthy=c['State']['Health']['Status'],disk_gib=round(free/1024**3,1),lan_dynamic=lan[0].get('dynamic'),models_unchanged=True)))
