import hashlib,json,pathlib,subprocess,shutil
R=pathlib.Path(__file__).resolve().parent.parent
def cmd(a):return subprocess.check_output(a,timeout=60)
def sha(p):return hashlib.sha256(pathlib.Path(p).read_bytes()).hexdigest()
d=json.loads(pathlib.Path('/etc/contextra-maintenance/server.json').read_text())
s=pathlib.Path(d['paths']['runtime'])/'state'
a=json.loads((s/'active.json').read_text())
ids=cmd(['docker','ps','-aq','--filter','label=com.docker.compose.project='+d['project']]).decode().split()
rows=json.loads(cmd(['docker','inspect',*ids]))
out=dict(server=d['server'],backend=d['backend'],project=d['project'],paths=d['paths'],active_transaction=a['transaction'],
 state_hashes={n:sha(s/n) for n in ('active.json','site.json','protected-bindings.json','input-baseline.json')},
 definition_sha256=sha('/etc/contextra-maintenance/server.json'),services={})
for row in rows:
 role=row['Config']['Labels']['com.docker.compose.service']
 env=dict(x.split('=',1) for x in row['Config']['Env'] if '=' in x)
 out['services'][role]=dict(id=row['Id'],image=row['Image'],running=row['State']['Running'],started=row['State']['StartedAt'],
  health=row['State'].get('Health',{}).get('Status'),mounts=row['Mounts'])
 if role=='analytics':
  out['config_paths']={k:env.get(k) for k in ('CONTEXTRA_CONTROL_TEMPLATE_FILE','STREAMS_CONFIG_PATH','STREAMS_RUNTIME_PATH')}
  dest=R/'baseline/app'
  if not dest.exists():
   dest.parent.mkdir(mode=0o700,exist_ok=True)
   cmd(['docker','cp',row['Id']+':/opt/contextra/app',str(dest)])
out['source_hashes']={str(p.relative_to(R/'baseline')):sha(p) for p in (R/'baseline/app').rglob('*') if p.is_file() and '__pycache__' not in p.parts}
out['tools_inventory_sha256']=sha(pathlib.Path(d['paths']['tools'])/'installed-files.json')
out['disk_free']={p:shutil.disk_usage(p).free for p in ('/','/data')}
assert out['disk_free']['/']>15*1024**3
(R/'baseline.json').write_text(json.dumps(out,indent=2));(R/'baseline.json').chmod(0o600)
print(json.dumps(dict(server=out['server'],backend=out['backend'],transaction=a['transaction'],services={k:v['image'] for k,v in out['services'].items()},source_files=len(out['source_hashes']))))
