# SPDX-License-Identifier: AGPL-3.0-only
# Copyright (c) 2026 sol pbc

from __future__ import annotations

import json
import threading
import time
from datetime import datetime, timedelta, timezone
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import Mock

import pytest
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.x509.oid import NameOID, ObjectIdentifier

from solstone.think.journal_io.locking import hold_lock
from solstone.think.models import AttestationFailedError
from solstone.think.providers import nvattest_install
from solstone.think.services import spp, spp_transport
from solstone.think.services.spp_attest.cadence import AttestationSession
from solstone.think.services.spp_attest.composite import verify_composite
from solstone.think.services.spp_attest.ratls.channel import RatlsChannelError
from solstone.think.services.spp_attest.ratls.contract import (
    COMPOSITE_EVIDENCE_OID,
    CompositeEvidence,
)
from solstone.think.services.spp_attest.ratls.verify import (
    RatlsVerificationError,
    verify_certificate_evidence,
)
from solstone.think.services.spp_attest.snp import Policy

SPP_FIXTURE_DIR = Path(__file__).resolve().parents[1] / "fixtures" / "spp_attest"


class _FakeChannel:
    def __init__(
        self,
        verdict: object,
        last_used_monotonic: float | None = None,
        epoch: int | None = None,
    ) -> None:
        self.verdict = verdict
        self.tls = object()
        self.last_used_monotonic = (
            time.monotonic() if last_used_monotonic is None else last_used_monotonic
        )
        self.epoch = spp_transport._EPOCH if epoch is None else epoch
        self.closed = False

    def close(self) -> None:
        self.closed = True


class _FakeLocal:
    def __init__(self) -> None:
        self.closed = False

    def close(self) -> None:
        self.closed = True


class _FakeListener:
    def __init__(self) -> None:
        self.closed = False

    def close(self) -> None:
        self.closed = True


class _AliveThread:
    def is_alive(self) -> bool:
        return True


@pytest.fixture(autouse=True)
def _clear_transport_state(monkeypatch: pytest.MonkeyPatch):
    monkeypatch.setattr(
        spp_transport,
        "ensure_nvattest_installed",
        lambda **_kwargs: SimpleNamespace(
            status="already_installed",
            nvattest_dir=Path("/tmp/solstone-nvattest-test"),
            reason_code=None,
            detail=None,
        ),
    )
    spp.delete_attestation_state()
    spp_transport.teardown_confidential_transport()
    yield
    spp.delete_attestation_state()
    spp_transport.teardown_confidential_transport()


def _write_confidential_config(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> dict:
    monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path))
    config = {
        "services": {
            "confidential": {
                "enabled_at": "2026-05-24T00:00:00Z",
                "account_id": "acct-test",
                "endpoint_url": "https://spp.example.test:9443",
                "served_model_id": "confidential-model",
                "credential_created_at": "2026-05-24T00:00:00Z",
                "credential_fingerprint_sha256": "fingerprint",
                "prior_active": {
                    "provider": "google",
                    "model": "gemini-3.5-flash",
                },
                "prior_local_endpoint": None,
            }
        }
    }
    config_dir = tmp_path / "config"
    config_dir.mkdir(parents=True)
    (config_dir / "journal.json").write_text(json.dumps(config), encoding="utf-8")
    return config["services"]["confidential"]


def _patch_listener(monkeypatch: pytest.MonkeyPatch) -> None:
    def fake_start_listener() -> None:
        spp_transport._LISTENER = _FakeListener()
        spp_transport._LISTENER_THREAD = _AliveThread()
        spp_transport._FORWARDER_BASE_URL = "http://127.0.0.1:4567"

    monkeypatch.setattr(spp_transport, "_start_listener_locked", fake_start_listener)


def _fixture_owner_nonce() -> bytes:
    return bytes.fromhex("".join((SPP_FIXTURE_DIR / "nonce.hex").read_text().split()))


def _fixture_composite_evidence(owner_nonce: bytes, spki: bytes) -> CompositeEvidence:
    certs_dir = SPP_FIXTURE_DIR / "certs"
    return CompositeEvidence(
        owner_nonce=owner_nonce,
        tls_spki_der=spki,
        amd_report=(SPP_FIXTURE_DIR / "report.bin").read_bytes(),
        hcl_report=(SPP_FIXTURE_DIR / "hcl_report.bin").read_bytes(),
        ak_public_key_pem=(SPP_FIXTURE_DIR / "akpub.pem").read_bytes(),
        quote_message=(SPP_FIXTURE_DIR / "quote.msg").read_bytes(),
        quote_signature=(SPP_FIXTURE_DIR / "quote.sig").read_bytes(),
        quote_pcrs=(SPP_FIXTURE_DIR / "quote.pcrs").read_bytes(),
        amd_ark_pem=(certs_dir / "ark.pem").read_bytes(),
        amd_ask_pem=(certs_dir / "ask.pem").read_bytes(),
        amd_vcek_pem=(certs_dir / "vcek.pem").read_bytes(),
        gpu_envelope=(SPP_FIXTURE_DIR / "gpu-envelope.tlv").read_bytes(),
    )


def _key_and_spki() -> tuple[ec.EllipticCurvePrivateKey, bytes]:
    key = ec.generate_private_key(ec.SECP256R1())
    spki = key.public_key().public_bytes(
        serialization.Encoding.DER,
        serialization.PublicFormat.SubjectPublicKeyInfo,
    )
    return key, spki


def _certificate_der(
    key: ec.EllipticCurvePrivateKey,
    evidence: CompositeEvidence,
) -> bytes:
    subject = issuer = x509.Name(
        [x509.NameAttribute(NameOID.COMMON_NAME, "spp-engine-test")]
    )
    cert = (
        x509.CertificateBuilder()
        .subject_name(subject)
        .issuer_name(issuer)
        .public_key(key.public_key())
        .serial_number(1001)
        .not_valid_before(datetime.now(timezone.utc) - timedelta(days=1))
        .not_valid_after(datetime.now(timezone.utc) + timedelta(days=1))
        .add_extension(
            x509.UnrecognizedExtension(
                ObjectIdentifier(COMPOSITE_EVIDENCE_OID),
                evidence.to_der(),
            ),
            critical=True,
        )
        .sign(key, hashes.SHA256())
    )
    return cert.public_bytes(serialization.Encoding.DER)


def _stale_session(verdict: object) -> AttestationSession:
    old = datetime.now(timezone.utc) - timedelta(hours=2)
    return AttestationSession(
        verdict=verdict,
        started_at=old,
        tpm_heartbeat_at=old,
        gpu_reattest_at=old,
    )


def test_establish_channel_locked_passes_production_pcr_policy(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    captured: dict[str, object] = {}

    def fake_establish(_endpoint, **kwargs):
        captured.update(kwargs)
        return _FakeChannel(object(), epoch=kwargs["epoch"])

    monkeypatch.setattr(spp_transport, "establish_attested_channel", fake_establish)

    spp_transport._establish_channel_locked(
        block,
        datetime.now(timezone.utc),
        nvattest_dir=tmp_path / "nvattest",
    )

    policy = captured["policy"]
    assert isinstance(policy, Policy)
    assert policy.pcr_mode == "pin"
    assert (
        "b162f46105c80d3e45028e37cc649404c9d65297ad1cda8f953208582060b0e3"
        in policy.pcr_pins
    )


def test_verify_confidential_attestation_reuses_then_rotates_stale_session_inline(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    _patch_listener(monkeypatch)
    verdict = object()

    def fake_establish(*_args, **kwargs):
        return _FakeChannel(verdict, epoch=kwargs["epoch"])

    establish = Mock(side_effect=fake_establish)
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)

    spp_transport.verify_confidential_attestation(block)
    spp_transport.verify_confidential_attestation(block)

    assert establish.call_count == 1
    assert spp.get_attestation_state().session is not None

    spp.record_attestation_verified(_stale_session(verdict))
    spp_transport.verify_confidential_attestation(block)

    assert establish.call_count == 2
    assert spp.get_attestation_state().session is not None
    assert (
        spp.get_attestation_state().session.status(datetime.now(timezone.utc))
        == "verified"
    )
    spp_transport.verify_confidential_attestation(block)
    assert establish.call_count == 2


def test_concurrent_stale_rotation_establishes_one_replacement(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    _patch_listener(monkeypatch)
    old_verdict = object()
    old_channel = _FakeChannel(old_verdict)
    spp.record_attestation_verified(_stale_session(old_verdict))
    with spp_transport._LOCK:
        spp_transport._LISTENER = _FakeListener()
        spp_transport._LISTENER_THREAD = _AliveThread()
        spp_transport._FORWARDER_BASE_URL = "http://127.0.0.1:1111"
        spp_transport._POOL[:] = [old_channel]

    ensure_barrier = threading.Barrier(2)
    ensure_calls = 0

    def delayed_ensure(_block):
        nonlocal ensure_calls
        ensure_calls += 1
        ensure_barrier.wait(timeout=2)
        return Path("/tmp/solstone-nvattest-test")

    establish_started = threading.Event()
    release_establish = threading.Event()

    def delayed_establish(*_args, **kwargs):
        establish_started.set()
        assert release_establish.wait(timeout=2)
        return _FakeChannel(object(), epoch=kwargs["epoch"])

    establish = Mock(side_effect=delayed_establish)
    monkeypatch.setattr(
        spp_transport,
        "_ensure_nvattest_for_attestation",
        delayed_ensure,
    )
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)

    errors: list[BaseException] = []

    def verify() -> None:
        try:
            spp_transport.verify_confidential_attestation(block)
        except BaseException as exc:  # pragma: no cover - surfaced below
            errors.append(exc)

    first = threading.Thread(target=verify)
    second = threading.Thread(target=verify)
    first.start()
    second.start()
    assert establish_started.wait(timeout=2)
    assert first.is_alive()
    assert second.is_alive()
    release_establish.set()
    first.join(timeout=2)
    second.join(timeout=2)

    assert errors == []
    assert not first.is_alive()
    assert not second.is_alive()
    assert ensure_calls == 2
    assert establish.call_count == 1
    assert old_channel.closed is True
    assert spp.get_attestation_state().session is not None


def test_confidential_egress_base_url_returns_forwarder_not_configured_endpoint(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    _patch_listener(monkeypatch)

    def fake_establish(*_args, **kwargs):
        return _FakeChannel(object(), epoch=kwargs["epoch"])

    establish = Mock(side_effect=fake_establish)
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)

    base_url = spp_transport.confidential_egress_base_url(block["endpoint_url"])

    assert base_url == "http://127.0.0.1:4567"
    assert base_url != block["endpoint_url"]
    assert establish.call_args.args[0].host == "spp.example.test"
    assert establish.call_args.args[0].port == 9443


def test_confidential_forwarder_base_url_rejects_inactive_lane(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path))
    config_dir = tmp_path / "config"
    config_dir.mkdir(parents=True)
    (config_dir / "journal.json").write_text("{}", encoding="utf-8")
    establish = Mock(side_effect=AssertionError("attestation attempted"))
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)

    with pytest.raises(spp_transport.ConfidentialLaneInactiveError) as exc_info:
        spp_transport.confidential_forwarder_base_url()

    assert exc_info.value.reason_code == "confidential_lane_inactive"
    establish.assert_not_called()


def test_confidential_forwarder_base_url_returns_verified_forwarder_only(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    _patch_listener(monkeypatch)

    def fake_establish(*_args, **kwargs):
        return _FakeChannel(object(), epoch=kwargs["epoch"])

    establish = Mock(side_effect=fake_establish)
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)

    base_url = spp_transport.confidential_forwarder_base_url()

    assert base_url == "http://127.0.0.1:4567"
    assert base_url != block["endpoint_url"]
    assert establish.call_args.args[0].host == "spp.example.test"
    assert establish.call_args.args[0].port == 9443


def test_confidential_forwarder_base_url_requires_verified_forwarder(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    _write_confidential_config(tmp_path, monkeypatch)
    monkeypatch.setattr(
        spp_transport,
        "verify_confidential_attestation",
        Mock(return_value=None),
    )

    with pytest.raises(AttestationFailedError):
        spp_transport.confidential_forwarder_base_url()


def test_stale_rotation_failure_returns_no_forwarder_and_later_recovers(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    _patch_listener(monkeypatch)
    old_verdict = object()
    spp.record_attestation_verified(_stale_session(old_verdict))
    old_channel = _FakeChannel(old_verdict)
    spp_transport._POOL[:] = [old_channel]
    establish = Mock(
        side_effect=[
            RatlsChannelError("gateway_unreachable"),
            _FakeChannel(object()),
        ]
    )
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)
    pump = Mock(return_value="local_closed")
    monkeypatch.setattr(spp_transport, "_pump", pump)

    with pytest.raises(AttestationFailedError):
        spp_transport.confidential_egress_base_url(block["endpoint_url"])
    assert old_channel.closed is True
    assert spp_transport._FORWARDER_BASE_URL is None
    assert spp_transport._LISTENER is None
    assert spp_transport._POOL == []
    assert spp_transport._ACTIVE == set()
    assert spp.get_attestation_state().session is None
    assert spp.get_attestation_state().failure is not None
    local = _FakeLocal()
    spp_transport._handle_loopback_connection(local)
    assert local.closed is True
    pump.assert_not_called()

    assert (
        spp_transport.confidential_egress_base_url(block["endpoint_url"])
        == "http://127.0.0.1:4567"
    )
    assert establish.call_count == 2
    assert spp.get_attestation_state().session is not None
    assert spp_transport._POOL
    assert all(channel is not old_channel for channel in spp_transport._POOL)


def test_confidential_probe_status_reads_state_without_attestation(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    _write_confidential_config(tmp_path, monkeypatch)
    establish = Mock(side_effect=AssertionError("attestation ceremony attempted"))
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)

    assert spp_transport.confidential_probe_status() == (
        False,
        "attestation_not_yet_verified",
    )

    now = datetime.now(timezone.utc)
    spp.record_attestation_verified(
        AttestationSession(
            verdict=object(),
            started_at=now,
            tpm_heartbeat_at=now,
            gpu_reattest_at=now,
        )
    )
    assert spp_transport.confidential_probe_status(now) == (True, None)

    spp.record_attestation_verified(_stale_session(object()))
    assert spp_transport.confidential_probe_status() == (False, "attestation_stale")

    spp.record_attestation_failed("unreachable", "gateway_unreachable")
    assert spp_transport.confidential_probe_status() == (
        False,
        "attestation_unreachable",
    )
    establish.assert_not_called()


def test_pooled_channels_older_than_idle_limit_are_discarded() -> None:
    stale = _FakeChannel(object(), last_used_monotonic=0.0)
    fresh = _FakeChannel(object(), last_used_monotonic=119.0)
    spp_transport._POOL[:] = [stale, fresh]

    spp_transport._discard_idle_locked(121.0)

    assert stale.closed is True
    assert fresh.closed is False
    assert spp_transport._POOL == [fresh]


def test_teardown_closes_checked_out_channel_and_prevents_repool(
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    _patch_listener(monkeypatch)
    verdict = object()
    now = datetime.now(timezone.utc)
    spp.record_attestation_verified(
        AttestationSession(
            verdict=verdict,
            started_at=now,
            tpm_heartbeat_at=now,
            gpu_reattest_at=now,
        )
    )
    channel = _FakeChannel(verdict)
    spp_transport._POOL[:] = [channel]
    local = _FakeLocal()

    def fake_pump(_local, _tls):
        assert channel in spp_transport._ACTIVE
        with spp_transport._LOCK:
            spp_transport._teardown_locked()
        return "local_closed"

    monkeypatch.setattr(spp_transport, "_pump", fake_pump)

    spp_transport._handle_loopback_connection(local)

    assert local.closed is True
    assert channel.closed is True
    assert channel not in spp_transport._POOL
    assert channel not in spp_transport._ACTIVE


def test_wrong_epoch_channel_is_not_checked_out() -> None:
    stale_epoch_channel = _FakeChannel(object(), epoch=spp_transport._EPOCH - 1)
    spp_transport._POOL[:] = [stale_epoch_channel]

    assert spp_transport._borrow_channel_locked(time.monotonic()) is None
    assert stale_epoch_channel.closed is True
    assert spp_transport._POOL == []


def test_refill_does_not_establish_while_nvattest_install_lock_is_held(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    now = datetime.now(timezone.utc)
    spp.record_attestation_verified(
        AttestationSession(
            verdict=object(),
            started_at=now,
            tpm_heartbeat_at=now,
            gpu_reattest_at=now,
        )
    )
    spec = nvattest_install.NvattestArchiveSpec(
        version="9.9.9",
        url="https://example.invalid/nvattest.tar.gz",
        archive_name="nvattest.tar.gz",
        sha256="a" * 64,
    )

    def cache_ready(**kwargs):
        return nvattest_install.nvattest_cache_ready(
            journal_path=tmp_path,
            spec=spec,
            **kwargs,
        )

    establish = Mock(side_effect=AssertionError("refill should not establish"))
    monkeypatch.setattr(spp_transport, "nvattest_cache_ready", cache_ready)
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)

    with hold_lock(nvattest_install._install_lock_path(tmp_path), timeout=1.0):
        with spp_transport._LOCK:
            spp_transport._CONFIDENTIAL_BLOCK = dict(block)
            channel = spp_transport._borrow_or_establish_channel_locked(now)

    assert channel is None
    establish.assert_not_called()
    assert spp.get_attestation_state().failure is None


RATLS_CHANNEL_REASON_CODES = (
    "gateway_unreachable",
    "tls_handshake_failed",
    "proof_http_failed",
)
RATLS_VERIFICATION_REASON_CODES = (
    "certificate_invalid",
    "certificate_extension_missing",
    "certificate_extension_not_critical",
    "certificate_extension_invalid",
    "certificate_evidence_invalid",
    "nonce_mismatch",
    "pcr_pin_mismatch",
    "spki_mismatch",
    "cpu_verification_failed",
    "gpu_nonce_mismatch",
    "nvattest_unavailable",
    "nvattest_integrity_failed",
    "gpu_appraisal_failed",
    "composite_appraisal_failed",
    "exporter_proof_invalid",
    "exporter_mismatch",
    "exporter_quote_failed",
)
BUCKETING_CASES = (
    tuple(
        ("channel", code, "unreachable" if code == "gateway_unreachable" else "failed")
        for code in RATLS_CHANNEL_REASON_CODES
    )
    + tuple(
        ("verification", code, "failed") for code in RATLS_VERIFICATION_REASON_CODES
    )
    + (
        ("endpoint", "endpoint_invalid", "failed"),
        ("unexpected", "unexpected_error", "failed"),
    )
)


@pytest.mark.parametrize(
    ("source", "reason_code", "kind"),
    BUCKETING_CASES,
    ids=[f"{source}:{reason_code}" for source, reason_code, _kind in BUCKETING_CASES],
)
def test_attestation_failure_buckets_real_reason_codes_at_transport_catch_site(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    source: str,
    reason_code: str,
    kind: str,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    if source == "channel":
        exc: Exception = RatlsChannelError(reason_code)
        monkeypatch.setattr(
            spp_transport, "establish_attested_channel", Mock(side_effect=exc)
        )
    elif source == "verification":
        exc = RatlsVerificationError(reason_code)
        monkeypatch.setattr(
            spp_transport, "establish_attested_channel", Mock(side_effect=exc)
        )
    elif source == "endpoint":
        block["endpoint_url"] = "not-a-url"
    elif source == "unexpected":
        monkeypatch.setattr(
            spp_transport,
            "establish_attested_channel",
            Mock(side_effect=RuntimeError("boom")),
        )

    with pytest.raises(AttestationFailedError):
        spp_transport.verify_confidential_attestation(block)

    failure = spp.get_attestation_state().failure
    assert failure is not None
    assert failure.kind == kind
    assert failure.reason_code == reason_code


def test_pcr_pin_mismatch_reason_records_from_real_composite_origin(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    observed: dict[str, str] = {}
    monkeypatch.setattr(
        spp_transport.secrets,
        "token_bytes",
        lambda _size: _fixture_owner_nonce(),
    )

    def fake_establish(_endpoint, **kwargs):
        key, spki = _key_and_spki()
        evidence = _fixture_composite_evidence(kwargs["owner_nonce"], spki)
        bad_policy = Policy(pcr_mode="pin", pcr_pins={"00" * 32})
        try:
            verify_certificate_evidence(
                certificate_der=_certificate_der(key, evidence),
                owner_nonce=kwargs["owner_nonce"],
                now=kwargs["now"],
                nvattest_dir=kwargs["nvattest_dir"],
                policy=bad_policy,
                quote_verifier=lambda **_kwargs: None,
                composite_verifier=verify_composite,
            )
        except RatlsVerificationError as exc:
            observed["reason_code"] = exc.reason_code
            raise
        raise AssertionError("fixture unexpectedly passed a non-matching PCR pin")

    monkeypatch.setattr(spp_transport, "establish_attested_channel", fake_establish)

    with pytest.raises(AttestationFailedError):
        spp_transport.verify_confidential_attestation(block)

    assert observed["reason_code"] == "pcr_pin_mismatch"
    failure = spp.get_attestation_state().failure
    assert failure is not None
    assert failure.kind == "failed"
    assert failure.reason_code == "pcr_pin_mismatch"


@pytest.mark.parametrize(
    ("status", "kind", "reason_code"),
    [
        ("install_in_flight", "unreachable", "nvattest_install_in_progress"),
        ("platform_unsupported", "failed", "nvattest_platform_unsupported"),
        ("install_failed", "failed", "nvattest_install_failed"),
    ],
)
def test_verify_confidential_attestation_records_nvattest_install_prerequisites(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
    status: str,
    kind: str,
    reason_code: str,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    establish = Mock(side_effect=AssertionError("verify should not run"))
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)
    monkeypatch.setattr(
        spp_transport,
        "ensure_nvattest_installed",
        lambda **_kwargs: SimpleNamespace(
            status=status,
            nvattest_dir=None,
            reason_code=None,
            detail=None,
        ),
    )

    with pytest.raises(AttestationFailedError):
        spp_transport.verify_confidential_attestation(block)

    establish.assert_not_called()
    failure = spp.get_attestation_state().failure
    assert failure is not None
    assert failure.kind == kind
    assert failure.reason_code == reason_code


def test_recheck_confidential_attestation_records_success(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    _patch_listener(monkeypatch)
    verdict = object()
    monkeypatch.setattr(
        spp_transport,
        "establish_attested_channel",
        Mock(return_value=_FakeChannel(verdict)),
    )

    spp_transport.recheck_confidential_attestation()

    state = spp.get_attestation_state()
    assert state.session is not None
    assert state.session.verdict is verdict
    assert state.failure is None
    assert state.last_verified is state.session
    assert spp_transport._FORWARDER_BASE_URL == "http://127.0.0.1:4567"
    assert block["endpoint_url"] == "https://spp.example.test:9443"


def test_recheck_confidential_attestation_ensures_nvattest_before_verify(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    block = _write_confidential_config(tmp_path, monkeypatch)
    _patch_listener(monkeypatch)
    nvattest_dir = tmp_path / "cache" / "providers" / "nvattest"
    ensured: list[dict[str, object]] = []

    def fake_ensure_nvattest_installed(**kwargs):
        ensured.append(kwargs)
        return SimpleNamespace(
            status="already_installed",
            nvattest_dir=nvattest_dir,
            reason_code=None,
            detail=None,
        )

    def fake_establish(_endpoint, **kwargs):
        assert ensured
        assert kwargs["nvattest_dir"] == nvattest_dir
        return _FakeChannel(object())

    monkeypatch.setattr(
        spp_transport, "ensure_nvattest_installed", fake_ensure_nvattest_installed
    )
    monkeypatch.setattr(spp_transport, "establish_attested_channel", fake_establish)

    spp_transport.recheck_confidential_attestation()

    assert ensured == [{"explicit_override": None}]
    assert spp.get_attestation_state().failure is None
    assert block["endpoint_url"] == "https://spp.example.test:9443"


def test_recheck_confidential_attestation_fails_closed_and_preserves_last_verified(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    _write_confidential_config(tmp_path, monkeypatch)
    prior = _stale_session(object())
    spp.record_attestation_verified(prior)
    monkeypatch.setattr(
        spp_transport,
        "establish_attested_channel",
        Mock(side_effect=RatlsChannelError("gateway_unreachable")),
    )

    spp_transport.recheck_confidential_attestation()

    state = spp.get_attestation_state()
    assert state.session is None
    assert state.last_verified is prior
    assert state.failure is not None
    assert state.failure.kind == "unreachable"
    assert state.failure.reason_code == "gateway_unreachable"


def test_recheck_confidential_attestation_off_is_noop(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path))
    config_dir = tmp_path / "config"
    config_dir.mkdir(parents=True)
    (config_dir / "journal.json").write_text("{}", encoding="utf-8")
    establish = Mock(side_effect=AssertionError("attestation attempted"))
    monkeypatch.setattr(spp_transport, "establish_attested_channel", establish)
    monkeypatch.setattr(
        spp_transport,
        "ensure_nvattest_installed",
        Mock(side_effect=AssertionError("nvattest ensure attempted")),
    )

    spp_transport.recheck_confidential_attestation()

    establish.assert_not_called()
    assert not (tmp_path / "cache" / "providers" / "nvattest").exists()
