#!/usr/bin/env python3
"""Candidate-bound entry point for the Task26 reconciliation observer v4."""

from __future__ import annotations

import hashlib
import importlib.util
import json
import subprocess
import sys
from pathlib import Path
from urllib.parse import unquote, urlparse
from types import ModuleType

ROOT = Path(__file__).resolve().parent
SOURCE = Path("/home/cube/projects/richard/hermes-agent")
INSTALLED = SOURCE / ".venv/lib/python3.12/site-packages"
DIRECT_URL = INSTALLED / "hermes_agent-0.17.0.dist-info/direct_url.json"
CANDIDATE = Path(
    "/home/cube/projects/richard/traning coach/.omo/evidence/task26/"
    "task26-clarification-normalized-successor-"
    "4e9962be49b72951c3b9ed7e1a4fe36d0ca03e757872ae03364c1ab7a790f32b"
)
SUCCESSOR = "4e9962be49b72951c3b9ed7e1a4fe36d0ca03e757872ae03364c1ab7a790f32b"
CORE = "88caabf3dee923e720463d917d35b6dd32ecc31102ed3ab4df4c6a203df4a760"
WHEEL = "33688875a0d1ce20955bd8272257ee34d84cb138f6a23a43e5d16682368ae5e5"
SOURCE_PARITY = {
    "gateway/platforms/nutrition_onboarding_reconciliation.py": "8fb6ba6f855e7508c525447cdec482ceb240f8c0a5827b2ca0ce4268c6880bb0",
    "gateway/platforms/telegram_nutrition_onboarding_copy.py": "8afb45c5cca082fd85cf07ab43dc5d1062c34678fd268a5722e313ce35cffd8b",
    "gateway/platforms/telegram_nutrition_onboarding_runtime.py": "3c24d49d656c623edfb95fcfbc7fb0f92365fc123420df66f733f9dbe39d704f",
    "gateway/platforms/telegram_nutrition_onboarding_runtime_callback.py": "bf2f312245b59ebf33dd1e3e449cfffed12809d18f820953cc28cecef25d34d2",
    "gateway/platforms/telegram_nutrition_onboarding_runtime_publication.py": "f04ea498ad12a257fb1322da4c8cfd2f91fc9403f0b978617fcc00df41729209",
}
PROFILE_SOURCE_PARITY = {
    "nutrition_onboarding.py": "d1f848d1fa8bc71e018f45c83e8e19e93671dfa83157d3feff15b8f7ec0f1d8a",
    "nutrition_onboarding_contract.py": "327267e12c2e6250218652811cca403a80c1704753f2caace7d8b1e446d21417",
}
PROFILE_PACKAGE = Path(
    "/home/cube/.hermes/profiles/dualcoachtest/workspace/checkin_cli/checkin_cli"
)


def digest(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()


def verify_binding() -> None:
    direct = json.loads(DIRECT_URL.read_text())
    installed_wheel = Path(unquote(urlparse(str(direct.get("url", ""))).path)).resolve()
    archive_hash = direct.get("archive_info", {}).get("hash")
    if (
        installed_wheel
        != (CANDIDATE / "artifacts/hermes_agent-0.17.0-py3-none-any.whl").resolve()
        or archive_hash != f"sha256={WHEEL}"
    ):
        raise RuntimeError("installed candidate wheel binding drift")
    result = subprocess.run(
        [sys.executable, str(CANDIDATE / "verify_candidate.py"), str(CANDIDATE)],
        check=True,
        capture_output=True,
        text=True,
    )
    verification = json.loads(result.stdout)
    manifest = json.loads((CANDIDATE / "candidate-manifest.json").read_text())
    if (
        verification.get("status") != "PASS"
        or verification.get("full") != SUCCESSOR
        or verification.get("core") != CORE
        or verification.get("wheel") != WHEEL
        or manifest.get("readiness") != "READY_FOR_FRESH_GATE18_20"
    ):
        raise RuntimeError("candidate verifier or digest binding drift")
    wheel = CANDIDATE / "artifacts/hermes_agent-0.17.0-py3-none-any.whl"
    if digest(wheel) != WHEEL:
        raise RuntimeError("candidate wheel drift")
    for relative, expected in SOURCE_PARITY.items():
        if digest(SOURCE / relative) != expected:
            raise RuntimeError(f"candidate source parity drift: {relative}")
        if digest(INSTALLED / relative) != expected:
            raise RuntimeError(f"installed wheel runtime drift: {relative}")
    for relative, expected in PROFILE_SOURCE_PARITY.items():
        if digest(PROFILE_PACKAGE / relative) != expected:
            raise RuntimeError(f"profile onboarding source drift: {relative}")


def load_observer() -> ModuleType:
    spec = importlib.util.spec_from_file_location(
        "task26_continuous_lifecycle_v4", ROOT / "continuous_lifecycle.py"
    )
    if spec is None or spec.loader is None:
        raise RuntimeError("observer import unavailable")
    module = importlib.util.module_from_spec(spec)
    sys.modules[spec.name] = module
    spec.loader.exec_module(module)
    if module.SUCCESSOR != SUCCESSOR or module.CORE != CORE or module.WHEEL != WHEEL:
        raise RuntimeError("observer digest binding drift")
    setattr(module, "SITE", INSTALLED)
    return module


def main() -> int:
    try:
        verify_binding()
        return int(load_observer().main())
    except (
        OSError,
        ValueError,
        RuntimeError,
        KeyError,
        subprocess.SubprocessError,
    ) as exc:
        print(f"FAIL: {exc}", file=sys.stderr)
        return 2


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