import json,os,pathlib,shutil,subprocess
from run import R,g,C,plan,built,api,redis_query,cmd
os.umask(0o077)
def main():
 assert not (R/'final.json').exists()
 d=json.loads((R/'run.json').read_text());assert d.get('maintained') and not d.get('error')
 c=g.inspect();assert c['Image']==built['image_id'] and c['State']['Health']['Status']=='healthy'
 assert api('/api/v1/streams')[1]['streams'][0]['state']=='stopped'
 assert c['HostConfig']['RestartPolicy']==plan['analytics']['HostConfig']['RestartPolicy']
 r=json.loads(g.sh(['docker','inspect','contextra-redis-1']))[0]
 access=json.loads((C/'access.json').read_text());passwords=json.loads((C/'secrets.json').read_text())
 previous=json.loads(pathlib.Path('/tmp/codex/ltb1021/2026-09-11_contextra-metadata-lan_r01/preflight.json').read_text())
 assert access['readers']==previous['test_readers'] and previous['site_reference_only'] not in access['readers']
 assert r['HostConfig']['PortBindings']=={'6379/tcp':[{'HostIp':access['host'],'HostPort':str(access['port'])}]}
 cmd(['python3',str(C/'firewall.py'),'check'])
 assert cmd(['systemctl','is-enabled','contextra-metadata-firewall.service']).stdout.strip()=='enabled'
 assert cmd(['systemctl','is-active','contextra-metadata-firewall.service']).stdout.strip()=='active'
 assert redis_query('reader','PING')=='PONG'
 assert 'off' in redis_query('admin','ACL','GETUSER','default')['flags']
 assert g.sha(g.ENV)==d['env_after'] and g.sha(g.CFG)==plan['config_hash']
 assert g.sha(g.CFG.parent/'2/model.plan')==plan['plan_hash']
 assert not (R/'visual/capture.enabled').exists()
 assert {k:v for k,v in g.others().items() if k!=r['Id']}==plan['other_containers']
 text=(R/'runtime.private.log').read_text()
 assert all(secret not in text for secret in passwords.values()),'SECRET_LOG_MATCH'
 handoff=C/'reader';handoff.mkdir(mode=0o700)
 for name in ('read_metadata.py','README.ko.md'):shutil.copyfile(R/'handoff'/name,handoff/name)
 conn=dict(host=access['host'],port=access['port'],namespace='contextra:metadata:v1')
 auth=dict(username='contextra_reader',password=passwords['reader'])
 (handoff/'connection.json').write_text(json.dumps(conn,indent=2))
 (handoff/'reader-credentials.json').write_text(json.dumps(auth,indent=2))
 # Actual reader example executes only reads inside the existing Analytics, with an internal endpoint.
 test=R/'visual/reader-selftest';test.mkdir(mode=0o700)
 shutil.copyfile(handoff/'read_metadata.py',test/'read_metadata.py')
 (test/'connection.json').write_text(json.dumps(dict(conn,host='redis',port=6379)))
 (test/'reader-credentials.json').write_text(json.dumps(auth))
 try:
  p=cmd(['docker','exec',g.NAME,'python3','/run/contextra-visual/reader-selftest/read_metadata.py',
   '--connection','/run/contextra-visual/reader-selftest/connection.json',
   '--credentials','/run/contextra-visual/reader-selftest/reader-credentials.json','--seconds','1'],10)
  assert '연결/인증 성공' in p.stdout and 'STOPPED' in p.stdout
  (R/'reader-selftest.log').write_text(p.stdout)
 finally:
  (test/'reader-credentials.json').unlink()
  (test/'connection.json').unlink()
 persistent=json.loads(g.sh(plan['persistent_compose']+['config','--format','json']))
 current=json.loads(g.sh(plan['compose']+['config','--format','json']))
 assert persistent['services']['analytics']['image']==built['image_id']
 assert persistent['services']['analytics']['restart']=='on-failure:3'
 assert not persistent['services']['analytics']['environment']['CONTEXTRA_START_DIAGNOSTICS_DIR']
 assert not persistent['services']['analytics']['environment']['CONTEXTRA_METADATA_VISUAL_DIR']
 for k in ('REDIS_URL','CONTEXTRA_METADATA_REDIS_URL','CONTEXTRA_METADATA_ENABLED'):
  actual=dict(x.split('=',1) for x in c['Config']['Env'])
  assert actual[k]==persistent['services']['analytics']['environment'][k]
 for x in handoff.iterdir():os.chmod(x,0o600)
 out=dict(analytics='healthy',stream='stopped',image=built['image_id'],reader_example_internal='PASS',
  host_lan_read='PASS',windows_test='NOT_RUN_NEXT_WEEK',default_recreate_without_diagnostics=True,
  retained_current_diagnostics=True,retained_visual_mount_capture_off=True,restart_restored=True,
  display_restored=True,non_targets_model_unchanged=True,secret_log_matches=0,port_bound_to_ai_lan=True,
  approved_readers=2,firewall_persistent_unit_enabled=True,gpu_mib=g.gpu(),handoff=str(handoff))
 (R/'final.json').write_text(json.dumps(out,indent=2));print(json.dumps(out))
if __name__=='__main__':main()
