"""Read-only health audit for the browser heartbeat release, run on the VPS."""
import hashlib,json,pathlib,re,shutil,subprocess,sys,urllib.error,urllib.request
task=sys.argv[1];assert re.fullmatch('[a-z0-9-]+',task)
root=pathlib.Path('/var/www/html/ro-th-online')
base=json.loads((root/'staging'/(task+'-baseline.json')).read_text())
manifest=json.loads((root/'deploy'/task/'release.json').read_text())
sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
pids={n:subprocess.check_output(['pgrep','-x',n],text=True).strip().splitlines() for n in base['gameServicePids']}
assert pids==base['gameServicePids'],'A game service PID changed'
units=['apache2','ro-th-online-gateway','ro-th-online-voice-rtc']
assert all(subprocess.check_output(['systemctl','is-active',u],text=True).strip()=='active' for u in units)
apkroot=pathlib.Path('/var/www/html/test-apk')
assert json.loads((apkroot/'apks/latest.json').read_text())==base['apk']
assert sha(apkroot/'patches/Maps/latest.json.gz')==base['mapCatalogHash']
assert subprocess.check_output(['systemctl','cat','ro-th-online-gateway'],text=True)==base['gatewayUnit']
config_path=pathlib.Path('/etc/apache2/sites-enabled/zz-ro-th-download-ssl.conf')
assert sha(config_path)==manifest['configHash']
config=config_path.read_text()
assert 'ProxyPass /bridge/voice-rtc ws://127.0.0.1:8090/bridge/voice-rtc' in config
owner=json.loads((root/'deploy'/task/'owner-release.json').read_text())
assert owner['release']==manifest['release'] and owner['beforeHash']==base['live']['owner']['sha256']
assert owner['indexHash']==sha(root/'public/index.html')
pages=[]
for path,status in [('/Mobile/',200),('/Mobile/?installed=1',200),('/browser/',401),('/',404)]:
    try:response=urllib.request.urlopen('https://ro-th.online'+path,timeout=30)
    except urllib.error.HTTPError as error:response=error
    with response:
        assert response.status==status
        if status==200:assert hashlib.sha256(response.read()).hexdigest()==manifest['indexHash']
    pages.append(dict(path=path,status=status))
retained=sorted(p.name for p in (root/'public/Build').glob('mobile-*') if p.is_dir())
result=dict(result='PASS',release=manifest['release'],gameServicePidsUnchanged=True,gameServicePids=pids,
            pages=pages,apacheGatewayRtcActive=True,rtcRoutePreserved=True,apkMetadataUnchanged=True,
            mapCatalogUnchanged=True,gatewayUnitUnchanged=True,ownerEntryVerified=True,retained=retained,freeBytes=shutil.disk_usage(root).free)
(root/'deploy'/task/'health.json').write_text(json.dumps(result,indent=2))
print(json.dumps(result,indent=2))
