from __future__ import annotations

import hashlib
import json
import os
import subprocess
from pathlib import Path


ROOT = Path(__file__).resolve().parent
SCRIPT = ROOT / "runtime_authority_bootstrap.py"
AUTHORIZATION = ROOT / "launch-authorization.json"
PYTHON = Path("/home/cube/projects/richard/hermes-agent/.venv/bin/python")
SOURCE = Path("/home/cube/projects/richard/hermes-agent-dualcoach-v1.1")


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


def _write_json(path: Path, value: dict[str, object]) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(value, sort_keys=True, separators=(",", ":")))
    path.chmod(0o600)


def _fixture(tmp_path: Path) -> tuple[Path, dict[str, Path], dict[str, str]]:
    profile = tmp_path / "profile"
    package = tmp_path / "package"
    external = tmp_path / "external"
    for path in (profile, package, external):
        path.mkdir(mode=0o700)
    paths = {
        "root": external / "authority",
        "pin": external / "task26-authority-pin.json",
        "candidate": external / "task26-candidate-digest",
        "receipt": external / "authority-receipt.json",
    }
    permission = tmp_path / "permission.json"
    _write_json(
        permission,
        {
            "schema": "dualcoach-runtime-authority-bootstrap-permission-v1",
            "profile": str(profile),
            "package_root": str(package),
            "authority_root": str(paths["root"]),
            "pin_path": str(paths["pin"]),
            "candidate_path": str(paths["candidate"]),
            "receipt_path": str(paths["receipt"]),
            "source_id": "dualcoach-v11-first-customer-test",
            "base_candidate": (
                "d1109d8f78aaccf949ec4f664d9e62584c3cca33032030518bc3e2d712239112"
            ),
            "base_pass_digest": (
                "31d7daa60dad93dce41761b2c36f1fe3ec38e8f9257761fd9b6771d83ac32a76"
            ),
            "candidate_digest": (
                "0e383539aea1b83205771772f1e8b417840defe60f5ea6ce184f80e3af8d25f9"
            ),
            "candidate_pass_digest": (
                "8f26a2929dd349967ecc39df3b750fdd84a2ded1dfd09ffe4ea27263746a7604"
            ),
            "authorization_path": str(AUTHORIZATION),
            "authorization_sha256": _sha(AUTHORIZATION),
            "script_sha256": _sha(SCRIPT) if SCRIPT.exists() else "0" * 64,
        },
    )
    env = {
        **os.environ,
        "PYTHONPATH": str(SOURCE),
        "PYTHONDONTWRITEBYTECODE": "1",
    }
    return permission, paths, env


def _run(
    permission: Path,
    env: dict[str, str],
) -> subprocess.CompletedProcess[str]:
    return subprocess.run(
        [
            str(PYTHON),
            "-B",
            str(SCRIPT),
            "--permission",
            str(permission),
        ],
        check=False,
        capture_output=True,
        text=True,
        env=env,
    )


def test_bootstrap_creates_two_event_external_authority(tmp_path: Path) -> None:
    permission, paths, env = _fixture(tmp_path)

    result = _run(permission, env)

    assert result.returncode == 0, result.stderr
    pin = json.loads(paths["pin"].read_text())
    registry = json.loads(
        (paths["root"] / "candidate-authority/registry.json").read_text()
    )
    assert pin["event_count"] == 2
    assert len(registry["events"]) == 2
    assert registry["current_qualified_candidate"] == (
        "0e383539aea1b83205771772f1e8b417840defe60f5ea6ce184f80e3af8d25f9"
    )
    assert paths["candidate"].read_text().strip() == (
        "0e383539aea1b83205771772f1e8b417840defe60f5ea6ce184f80e3af8d25f9"
    )
    assert json.loads(paths["receipt"].read_text())["status"] == "PASS_PREPARED"


def test_bootstrap_is_one_use(tmp_path: Path) -> None:
    permission, _, env = _fixture(tmp_path)
    assert _run(permission, env).returncode == 0

    repeated = _run(permission, env)

    assert repeated.returncode == 2


def test_bootstrap_rejects_unbound_authorization_before_creation(
    tmp_path: Path,
) -> None:
    permission, paths, env = _fixture(tmp_path)
    value = json.loads(permission.read_text())
    value["authorization_sha256"] = "f" * 64
    _write_json(permission, value)

    result = _run(permission, env)

    assert result.returncode == 2
    assert not paths["root"].exists()
