"""Install the previously reviewed, hash-verified GUI package set; no GUI start."""
import hashlib
import json
import os
from pathlib import Path
import re
import subprocess

STAGE = Path("/home/si/.local/share/contextra-offline-prep/20260928-r01")


def main():
    if os.geteuid() != 0:
        raise RuntimeError("This reviewed one-time package install requires sudo")
    manifest = json.loads((STAGE / "gui-manifest.json").read_text())
    files = []
    for package in manifest["packages"]:
        path = STAGE / "gui-debs" / package["local_file"]
        if path.is_symlink() or not path.is_file():
            raise RuntimeError("Unexpected package file type")
        if path.stat().st_size != package["size_bytes"]:
            raise RuntimeError("Package size mismatch")
        with path.open("rb") as stream:
            digest = hashlib.file_digest(stream, "sha256").hexdigest()
        if digest != package["sha256"]:
            raise RuntimeError("Package hash mismatch")
        files.append(str(path))
    common = ["apt-get", "--no-install-recommends",
              "-o", "DPkg::Lock::Timeout=30"]
    env = dict(os.environ, LC_ALL="C", DEBIAN_FRONTEND="noninteractive", NEEDRESTART_MODE="l")
    planned = subprocess.run(common + ["--simulate", "install", *files],
        capture_output=True, text=True, timeout=60, env=env)
    if planned.returncode:
        print(planned.stdout[-3000:] + planned.stderr[-1800:])
        raise RuntimeError("GUI plan failed before installation")
    match = re.search(r"(\d+) upgraded, (\d+) newly installed, (\d+) to remove", planned.stdout)
    if not match or int(match[1]) or int(match[3]):
        raise RuntimeError("Plan contains existing-package changes; install not executed")
    if int(match[2]) != manifest["installs"]:
        raise RuntimeError("GUI install plan drifted")
    print(json.dumps(dict(phase="plan", installs=int(match[2]), upgrades=0, removals=0)), flush=True)
    # All dependencies were resolved above. dpkg consumes only the verified local DEBs.
    result = subprocess.run(["dpkg", "--install", *files],
        capture_output=True, text=True, timeout=600, env=env)
    log = STAGE / "gui-install.log"
    fd = os.open(log, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
    with os.fdopen(fd, "w") as stream:
        stream.write(result.stdout + result.stderr)
    if result.returncode:
        print(result.stdout[-1600:] + result.stderr[-1600:])
        raise RuntimeError("GUI package install failed; no automatic retry")
    print(json.dumps(dict(status="GUI_PACKAGES_INSTALLED", gui_started=False,
                          display_manager_installed=False, autostart_added=False)))


if __name__ == "__main__":
    main()
