import json,pathlib,subprocess,time,urllib.request
from build import g,R
from apply import plan,restart_arg
def main():
 state=json.loads((R/'apply.json').read_text());assert state.get('rollback')=='applied'
 c=g.inspect();assert c['Image']==plan['analytics']['Image']
 subprocess.run(['docker','update','--restart='+restart_arg(plan['analytics']['HostConfig']['RestartPolicy']),g.NAME],capture_output=True,check=True,timeout=15)
 env=g.load_env_file(str(g.ENV));opener=urllib.request.build_opener(urllib.request.ProxyHandler({}))
 def api(path):
  with opener.open('http://127.0.0.1:'+env['FASTAPI_HOST_PORT']+path,timeout=3) as f:return json.load(f)
 end=time.monotonic()+90
 while time.monotonic()<end:
  c=g.inspect()
  try:
   if c['State'].get('Health',{}).get('Status')=='healthy' and api('/ready')['ready']:break
  except Exception:pass
  time.sleep(2)
 states=api('/api/v1/streams')['streams'];assert len(states)==1 and states[0]['state']=='stopped'
 r=json.loads(g.sh(['docker','inspect','contextra-redis-1']))[0]
 others={k:v for k,v in g.others().items() if k!=r['Id']}
 assert others==plan['other_containers']
 assert not r['HostConfig']['PortBindings']
 assert 'nopass' in g.sh(['docker','exec',r['Id'],'redis-cli','ACL','LIST'])
 assert g.sha(g.ENV)==plan['env_hash']
 assert g.sha(pathlib.Path(env['CONTEXTRA_RUNTIME_STATE_ROOT'])/'streams_runtime.yaml')==plan['overlay_hash']
 assert not pathlib.Path(plan['unit']).exists()
 assert subprocess.run(['iptables','-S','CTX_METADATA_LAN'],capture_output=True).returncode!=0
 events=subprocess.check_output(['docker','events','--since','30m','--until','0s','--filter','type=container','--filter','event=die','--format','{{json .}}'],text=True,timeout=10)
 died=[]
 for line in events.splitlines():
  e=json.loads(line);attrs=e['Actor']['Attributes']
  if attrs.get('image')==json.loads((R/'build.json').read_text())['tag']:
   died.append(dict(exit_code=attrs.get('exitCode'),duration=attrs.get('execDuration'),time=e['time']))
 out=dict(analytics=c['State']['Status'],health=c['State'].get('Health',{}).get('Status'),
          stream='stopped',restart_restored=c['HostConfig']['RestartPolicy']==plan['analytics']['HostConfig']['RestartPolicy'],
          redis_restored=True,port_absent=True,firewall_removed=True,env_restored=True,overlay_unchanged=True,
          other_containers_unchanged=True,gpu_mib=g.gpu(),start=0,stop=0,failed_image_events=died,
          model_unchanged=g.sha(g.CFG)==plan['config_hash'] and g.sha(g.CFG.parent/'2/model.plan')==plan['plan_hash'])
 (R/'final.json').write_text(json.dumps(out,indent=2));print(json.dumps(out))
if __name__=='__main__':main()
