"""VPS read-only final checks and removal of this release's verified upload copies."""
import hashlib,json,pathlib,subprocess,urllib.error,urllib.request,urllib.parse,sys,re
root=pathlib.Path('/var/www/html/ro-th-online').resolve(strict=True)
task,shell_hash=sys.argv[1:];assert re.fullmatch('[a-z0-9-]+',task) and re.fullmatch('[a-f0-9]{64}',shell_hash)
baseline=json.loads((root/'staging'/(task+'-baseline.json')).read_text(encoding='utf-8-sig'))
record=json.loads((root/'deploy'/task/'release.json').read_text())
owner=json.loads((root/'deploy'/task/'owner-release.json').read_text())
retention=json.loads((root/f'deploy/browser-retention-completed-{task}.json').read_text())
sha=lambda path:hashlib.sha256(path.read_bytes()).hexdigest()
assert sha(root/'mobile/index.html')==record['indexHash']
assert sha(root/'public/index.html')==owner['indexHash']
assert sha(pathlib.Path('/etc/apache2/sites-enabled/zz-ro-th-download-ssl.conf').resolve())==record['configHash']
assert 'ProxyPass /bridge/voice-rtc ws://127.0.0.1:8090/bridge/voice-rtc' in pathlib.Path('/etc/apache2/sites-enabled/zz-ro-th-download-ssl.conf').read_text()
assert json.loads(pathlib.Path('/var/www/html/test-apk/apks/latest.json').read_text())==baseline['apk'],'APK metadata changed'
assert sha(pathlib.Path('/var/www/html/test-apk/patches/Maps/latest.json.gz'))==baseline['mapCatalogHash'],'APK map catalog changed'
maps_root=root/'content/browser-maps'/task
maps=json.loads((maps_root/'verified.json').read_text())
assert maps['verified'] and len(maps['maps'])==91
map_results=[]
for row in maps['maps']:
    p=maps_root/(row['map']+'.bytes')
    assert sha(p)==row['sha256']
    req=urllib.request.Request('https://ro-th.online/content/maps/'+urllib.parse.quote(row['map'])+'/map.bytes')
    with urllib.request.urlopen(req,timeout=180) as response:
        assert response.status==200 and response.headers.get('Cache-Control')=='no-store'
        digest=hashlib.sha256()
        while chunk:=response.read(1024*1024):digest.update(chunk)
        assert digest.hexdigest()==row['sha256'],row['map']
    map_results.append(dict(map=row['map'],sha256=row['sha256'],sourceArchiveHash=row['sourceArchiveHash'],httpsVerified=True))
for name,expected in baseline['gameServicePids'].items():
    assert subprocess.check_output(['pgrep','-x',name],text=True).strip().splitlines()==expected,name+' PIDs changed'
assert subprocess.check_output(['systemctl','is-active','apache2','ro-th-online-gateway','ro-th-online-voice-rtc'],text=True).splitlines()==['active']*3
kept=sorted(path.name for path in (root/'public/Build').glob('mobile-*') if path.is_dir())
assert kept==sorted('mobile-'+value for value in retention['keep']) and retention['verifiedRetained']
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()==record['indexHash']
    pages.append(dict(path=path,status=status))
removed=[]
for path,expected in [(root/'staging'/f'{task}-build.tar.gz',record['archiveHash']),
                     (root/'staging'/f'{task}-shell.tar',shell_hash),
                     (root/'staging'/f'{task}-maps.tar.gz',maps['archiveHash'])]:
    assert path.is_file() and not path.is_symlink() and path.resolve(strict=True).parent==root/'staging'
    assert sha(path)==expected
    removed.append(dict(path=str(path.relative_to(root)),bytes=path.stat().st_size,sha256=expected));path.unlink()
result=dict(release=record['release'],pages=pages,gameServicePidsUnchanged=True,apacheGatewayVoiceActive=True,rtcRoutePreserved=True,retained=kept,retired=retention['retired'],removedUploadCopies=removed,apkMetadataUnchanged=True,ownerAuthenticationUnchanged=owner['authenticationUnchanged'])
result.update(mapCatalogUnchanged=True,browserMaps=map_results)
(root/'deploy'/task/'health.json').write_text(json.dumps(result,indent=2))
print(json.dumps(result,indent=2))
