#!/usr/bin/env python3
"""Independent verifier for the Task26 v3 archive and clean live baseline."""

from __future__ import annotations

import hashlib
import json
import os
import stat
import subprocess
from pathlib import Path
from typing import Any

PROFILE = Path("/home/cube/.hermes/profiles/dualcoachtest")
ARCHIVE = PROFILE / "data/post-lifecycle-cleanup-archives/task26-current-4a6c7ee5-20260817"
CONTRACT = Path(__file__).with_name("schema-contract-v3.json")


def canon(value: Any) -> bytes:
    return (json.dumps(value, sort_keys=True, separators=(",", ":")) + "\n").encode()


def sha(raw: bytes) -> str:
    return hashlib.sha256(raw).hexdigest()


def check(condition: bool, message: str) -> None:
    if not condition:
        raise RuntimeError(message)


def inventory(root: Path) -> str:
    rows: list[dict[str, Any]] = []
    for base, dirs, files in os.walk(root, followlinks=False):
        dirs.sort()
        files.sort()
        for name in list(dirs):
            path = Path(base) / name
            st = path.lstat()
            rel = path.relative_to(root).as_posix()
            if stat.S_ISLNK(st.st_mode):
                rows.append({"path": rel, "type": "L", "target": os.readlink(path), "mode": f"{stat.S_IMODE(st.st_mode):04o}"})
                dirs.remove(name)
            else:
                check(stat.S_ISDIR(st.st_mode), f"unsafe unrelated directory: {path}")
                rows.append({"path": rel, "type": "D", "mode": f"{stat.S_IMODE(st.st_mode):04o}"})
        for name in files:
            path = Path(base) / name
            st = path.lstat()
            rel = path.relative_to(root).as_posix()
            if stat.S_ISLNK(st.st_mode):
                rows.append({"path": rel, "type": "L", "target": os.readlink(path), "mode": f"{stat.S_IMODE(st.st_mode):04o}"})
                continue
            check(stat.S_ISREG(st.st_mode), f"unsafe unrelated entry: {path}")
            raw = path.read_bytes()
            rows.append({"path": rel, "type": "F", "size": len(raw), "sha256": sha(raw), "mode": f"{stat.S_IMODE(st.st_mode):04o}"})
    return sha(canon(rows))


def main() -> int:
    contract = json.loads(CONTRACT.read_text())
    manifest_raw = (ARCHIVE / "manifest.json").read_bytes()
    manifest = json.loads(manifest_raw)
    receipt = json.loads((ARCHIVE / "receipt.json").read_text())
    check(manifest["schema"] == "task26-post-lifecycle-cleanup-archive-v3", "archive schema")
    check(receipt["status"] == "PASS", "cleanup receipt")
    claimed = manifest.pop("evidence_digest")
    check(claimed == sha(canon(manifest)), "manifest evidence seal")
    manifest["evidence_digest"] = claimed
    for row in manifest["entries"]:
        path = ARCHIVE / "payload" / row["path"]
        raw = path.read_bytes()
        check(len(raw) == row["size"] and sha(raw) == row["sha256"], f"payload: {row['path']}")
        check(stat.S_IMODE(path.stat().st_mode) == 0o600, f"payload mode: {row['path']}")
    delivery = json.loads((ARCHIVE / "payload/data/owner-actions/draft-deliveries.json").read_text())
    check(list(delivery) == ["e7d63548ceecf2fd:58f2cda7abd532c0d6e145bbb3f3216609b004374adab8bfae2ee28dc5d7d660"], "delivery uniqueness")
    row = next(iter(delivery.values()))
    check(row["status"] == "sent_audited" and str(row["message_id"]) == "232", "delivery outcome")
    bootstrap = json.loads((ARCHIVE / "payload/data/onboarding/telegram-customer-bootstrap-v1/ledger.json").read_text())
    check(sum(item.get("state") == "ACTIVE" for item in bootstrap["sessions"]) == 1, "ACTIVE history")
    for rel in ("customers", "data/customers", "data/onboarding", "data/owner-actions", "gateway.lock", "gateway.pid", "gateway_state.json", "state.db", "state.db-shm", "state.db-wal"):
        check(not (PROFILE / rel).exists(), f"live residue: {rel}")
    config = (PROFILE / "config.yaml").read_text()
    for token in ("        enabled: true", "        delivery_enabled: false", "        activation: false", "        delivery: false"):
        check(token in config, f"config token: {token}")
    check(stat.S_IMODE((PROFILE / "config.yaml").stat().st_mode) == 0o664, "config mode")
    show = subprocess.run(["/usr/bin/systemctl", "--user", "show", contract["service"]["name"], "--property=ActiveState,SubState,MainPID"], capture_output=True, text=True, check=True)
    service_values = dict(line.split("=", 1) for line in show.stdout.splitlines() if "=" in line)
    check(service_values == {"MainPID": "0", "ActiveState": "inactive", "SubState": "dead"}, "service state")
    check(inventory(Path("/home/cube/.hermes/profiles/physique-coach")) == manifest["unrelated_profiles_pre_sha256"]["/home/cube/.hermes/profiles/physique-coach"], "unrelated profile")
    for path, expected in contract["protected_files"].items():
        check(sha(Path(path).read_bytes()) == expected, f"protected authority: {path}")
    result = {"schema": "task26-post-lifecycle-independent-verification-v3", "status": "PASS", "archive": str(ARCHIVE), "archive_manifest_sha256": sha(manifest_raw), "checks": 12 + len(manifest["entries"]), "delivery_history_preserved": True, "active_history_preserved": True, "clean_baseline": True, "unrelated_profile_unchanged": True}
    print(json.dumps(result, sort_keys=True, separators=(",", ":")))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
