"""Publish only the verified Mobile canvas-density setting, with HTML rollback."""
import datetime
import hashlib
import json
import os
from pathlib import Path
import shutil
import urllib.error
import urllib.request

ROOT = Path('/var/www/html/ro-th-online')
INDEX = ROOT / 'mobile/index.html'
STAGED = ROOT / 'staging/mobile-density-20260929.html'
BACKUP = ROOT / 'deploy/mobile-density-20260929'
OLD = '1df4576c268956e9ca2ef628213e81a66931cdc5a6247ede4a54cc42a187abc4'
NEW = '7823f526149a0d3378337e021aef4e5bf44e2aadc4127575c60775960e5454e4'
BEFORE = '          devicePixelRatio: isAppleMobile || /Android/i.test(navigator.userAgent) ? 1 : undefined,'
AFTER = '''          // Keep text sharp on dense displays without the 9x framebuffer cost of DPR 3.
          // The CSS viewport and input coordinates keep their existing size.
          devicePixelRatio: isAppleMobile || isAndroidMobile ? Math.min(2, Math.max(1, window.devicePixelRatio || 1)) : undefined,'''


def sha(path):
    return hashlib.sha256(path.read_bytes()).hexdigest()


def request(path):
    try:
        return urllib.request.urlopen(urllib.request.Request('https://ro-th.online' + path,
            headers={'Cache-Control': 'no-cache', 'Accept-Encoding': 'identity'}), timeout=30)
    except urllib.error.HTTPError as error:
        return error


assert not INDEX.is_symlink() and not STAGED.is_symlink() and not BACKUP.exists()
assert sha(INDEX) == OLD and sha(STAGED) == NEW
old = INDEX.read_text()
assert old.count(BEFORE) == 1 and old.replace(BEFORE, AFTER) == STAGED.read_text()
record = json.loads((ROOT / 'deploy/autoattack-gestures-20260929/release.json').read_text())
assert record['release'] == 'mobile-f398e377' and record['indexHash'] == OLD
owner_hash = sha(ROOT / 'public/index.html')
config = Path('/etc/apache2/sites-enabled/zz-ro-th-download-ssl.conf')
assert sha(config) == record['configHash']
retained = sorted(p.name for p in (ROOT / 'public/Build').glob('mobile-*'))
assert retained == ['mobile-14515af5', 'mobile-89773500', 'mobile-f398e377']
for name, expected in record['files'].items():
    if name != 'WebPreview.data':
        assert sha(ROOT / 'public/Build' / record['release'] / name) == expected['sha256']
BACKUP.mkdir(mode=0o700)
shutil.copy2(INDEX, BACKUP / 'index-before.html')
info = INDEX.stat()
os.chmod(STAGED, info.st_mode)
os.chown(STAGED, info.st_uid, info.st_gid)
assert sha(INDEX) == OLD
os.replace(STAGED, INDEX)
try:
    for path in ['/Mobile/', '/Mobile/?installed=1']:
        with request(path) as response:
            assert response.status == 200 and hashlib.sha256(response.read()).hexdigest() == NEW
    with request('/browser/') as response:
        assert response.status == 401
    assert sha(ROOT / 'public/index.html') == owner_hash and sha(config) == record['configHash']
    assert sorted(p.name for p in (ROOT / 'public/Build').glob('mobile-*')) == retained
except Exception:
    shutil.copy2(BACKUP / 'index-before.html', INDEX)
    raise
record.update(previousIndexHash=OLD, indexHash=NEW, htmlOnly=True,
              publishedAtUtc=datetime.datetime.now(datetime.timezone.utc).isoformat(),
              densityPolicy='Mobile uses display DPR clamped to [1,2]; desktop unchanged',
              retainedReleases=retained, ownerIndexHash=owner_hash)
(BACKUP / 'release.json').write_text(json.dumps(record, indent=2))
print(json.dumps(record, indent=2))
