"""V14 pre-reservation, import, and service-lifecycle safety regressions."""

from __future__ import annotations

import hashlib
import json
import os
from pathlib import Path
from typing import final
from unittest.mock import patch

import pytest

import scripts.nutricoach_v150_sealed_controller as sealed_controller
from scripts.nutricoach_v150_concrete_host import ConcreteLiveHost
from scripts.nutricoach_v150_detached_bootstrap import (
    BootstrapDenied,
    verified_pythonpath,
)
from scripts.nutricoach_v150_host_operations import service_state
from scripts.nutricoach_v150_sealed_controller import (
    APPROVAL_PHRASE,
    DisposableService,
    SealedControllerError,
    execute_disposable,
)
from tests.test_nutricoach_v150_sealed_controller import target_fixture


@final
class ObservedService:
    def __init__(self, *, sticky_stop: bool = False) -> None:
        self.running = True
        self.sticky_stop = sticky_stop

    def stop(self) -> None:
        if not self.sticky_stop:
            self.running = False

    def reload(self) -> None:
        return None

    def start(self) -> None:
        self.running = True

    def observe(self) -> dict[str, str]:
        return {
            "ActiveState": "active" if self.running else "inactive",
            "SubState": "running" if self.running else "dead",
            "MainPID": "401" if self.running else "0",
            "ExecStart": "/observed/runtime/bin/python -m gateway.run",
            "ExecMainStartTimestampMonotonic": "700",
        }


def test_detached_bootstrap_verifies_wheels_before_source(tmp_path: Path) -> None:
    wheels: list[dict[str, str]] = []
    for name in ("hermes.whl", "profile.whl"):
        path = tmp_path / name
        _ = path.write_bytes(name.encode())
        path.chmod(0o444)
        wheels.append({
            "path": str(path),
            "sha256": hashlib.sha256(path.read_bytes()).hexdigest(),
        })
    target = tmp_path / "sealed-target.json"
    _ = target.write_text(json.dumps({"wheels": wheels}) + "\n")
    source = tmp_path / "source"

    pythonpath = verified_pythonpath(target, source)

    assert pythonpath.split(os.pathsep) == [
        str(tmp_path / "hermes.whl"),
        str(tmp_path / "profile.whl"),
        str(source),
    ]
    hermes = tmp_path / "hermes.whl"
    hermes.chmod(0o644)
    _ = hermes.write_bytes(b"tampered")
    hermes.chmod(0o444)
    with pytest.raises(BootstrapDenied, match="wheel_integrity"):
        _ = verified_pythonpath(target, source)


def test_expired_weekly_authority_is_denied_before_ledger_reservation(
    tmp_path: Path,
) -> None:
    _ = target_fixture(tmp_path)
    host = ConcreteLiveHost.disposable(tmp_path, DisposableService())

    with (
        patch.object(
            sealed_controller,
            "WEEKLY_AUTHORITY_EXPIRES_AT",
            "2020-01-01T00:00:00+00:00",
        ),
        pytest.raises(SealedControllerError, match="weekly_authority_window"),
    ):
        _ = execute_disposable(APPROVAL_PHRASE, tmp_path, host)

    assert not host.ledger_reserved()
    assert not host.ledger_consumed()


def test_service_state_preserves_manager_observed_exec_start(
    tmp_path: Path,
) -> None:
    _ = target_fixture(tmp_path)
    host = ConcreteLiveHost.disposable(tmp_path, DisposableService())

    state = service_state(ObservedService(), host.paths)

    assert state["ExecStart"] == "/observed/runtime/bin/python -m gateway.run"


def test_host_stop_denies_service_that_remains_running(tmp_path: Path) -> None:
    _ = target_fixture(tmp_path)
    disposable = ConcreteLiveHost.disposable(tmp_path, DisposableService())
    host = ConcreteLiveHost(
        disposable.paths,
        ObservedService(sticky_stop=True),
        live=False,
    )

    with pytest.raises(RuntimeError, match="service_stop"):
        host.stop()
