"""Install independent offline-maintenance tools; do not activate Runtime or source."""
import hashlib
import json
import os
from pathlib import Path
import shutil
import subprocess
import tarfile

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


def checksum(path):
    with path.open("rb") as stream:
        return hashlib.file_digest(stream, "sha256").hexdigest()


def verify_archive(path):
    with tarfile.open(path) as archive:
        names = set(archive.getnames())
        data = json.load(archive.extractfile("manifest.json"))
        for row in data:
            if not all(name in names for name in [row["Config"], *row["Layers"]]):
                raise ValueError("Image export is missing layers: " + path.name)


def main():
    if os.geteuid() != 0:
        raise RuntimeError("One-time installation requires sudo")
    if Path("/usr/local/bin/ct").exists() and checksum(Path("/usr/local/bin/ct")) != checksum(STAGE / "maintenance/ct"):
        raise RuntimeError("Existing installation preserved; review first")
    if PREFIX.exists():
        for path in PREFIX.iterdir():
            if path.name == "__pycache__":
                continue
            expected = STAGE / "maintenance" / path.name
            if path.name == "stop_channels.py":
                expected = STAGE / path.name
            if path.name == "observability.py":
                continue  # Owned installer correction; no application files share this prefix.
            if path.is_symlink() or not expected.is_file() or checksum(path) != checksum(expected):
                raise RuntimeError("Partial installation differs; no overwrite")
    records = json.loads((STAGE / "observability/images.json").read_text())
    graf = json.loads((STAGE / "observability/grafana-materialized/images.json").read_text())["images"][0]
    for row in records["images"]:
        if row["tag"] == "grafana/grafana:13.2.2":
            row.update(graf)
            path = STAGE / "observability/grafana-materialized" / row["filename"]
        else:
            path = STAGE / "observability" / row["filename"]
        if path.stat().st_size != row["size_bytes"] or checksum(path) != row["sha256"]:
            raise RuntimeError("Image checksum mismatch")
        verify_archive(path)
        result = subprocess.run(["docker", "image", "inspect", row["image_id"]], capture_output=True, timeout=10)
        if result.returncode != 0:
            subprocess.run(["docker", "load", "--input", str(path)], check=True, timeout=300)
        actual = json.loads(subprocess.run(["docker", "image", "inspect", row["tag"]],
            check=True, capture_output=True, text=True, timeout=15).stdout)[0]
        with tarfile.open(path) as archive:
            exported = json.load(archive.extractfile("manifest.json"))[0]
            config = json.load(archive.extractfile(exported["Config"]))
        if actual["Architecture"] != "amd64" or actual["RootFS"]["Layers"] != config["rootfs"]["diff_ids"]:
            raise RuntimeError("Daemon image layers differ from verified offline archive")
        row["engine_image_id"] = actual["Id"]
    PREFIX.mkdir(parents=True, mode=0o755, exist_ok=True)
    for path in (STAGE / "maintenance").glob("*.py"):
        if path.name.startswith("test_"):
            continue
        shutil.copyfile(path, PREFIX / path.name)
        (PREFIX / path.name).chmod(0o644)
    shutil.copytree(STAGE/"maintenance/bridge_tools",PREFIX/"bridge_tools",ignore=shutil.ignore_patterns("__pycache__"))
    shutil.copyfile(STAGE / "stop_channels.py", PREFIX / "stop_channels.py")
    shutil.copyfile(STAGE / "maintenance/ct", "/usr/local/bin/ct")
    Path("/usr/local/bin/ct").chmod(0o755)
    import sys
    sys.path.insert(0, str(PREFIX))
    import observability
    observability.prepare(records)
    unit = Path("/etc/systemd/system/contextra-gpu-metrics.service")
    if unit.exists():
        raise RuntimeError("Existing GPU collector unit preserved")
    unit.write_text("""[Unit]
Description=Manual low-frequency Contextra GPU metrics
After=local-fs.target
ConditionPathIsMountPoint=/backup

[Service]
Type=simple
User=si
Group=si
ExecStart=/usr/bin/python3 /usr/local/lib/contextra-maintenance/20260928-r01/gpu_metrics.py /backup/contextra/observability/textfile
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/backup/contextra/observability/textfile
PrivateTmp=yes
MemoryMax=128M
CPUQuota=10%
TimeoutStopSec=10
Restart=no
""")
    (STAGE / "observability/verified-images.json").write_text(json.dumps(records, indent=2))
    print("TOOLS_INSTALLED; MONITORING_NOT_STARTED; SYSTEMD_RELOAD_DEFERRED; SOURCE_RUNTIME_AUTH_UNCHANGED")


if __name__ == "__main__":
    main()
