from __future__ import annotations

from contextlib import contextmanager
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import AsyncMock, Mock

import pytest

import gateway.platforms.dualcoach_activation_cutover as cutover_module
import gateway.platforms.task26_runtime_authority as authority_module
from gateway.platforms import dualcoach_admin


class _FakeAuthoritySource:
    def __init__(self, *_args: object, **_kwargs: object) -> None:
        pass

    @contextmanager
    def authorize(
        self,
        _candidate: str,
        _stage: str,
    ):
        yield SimpleNamespace()


def test_customer_activate_replay_preserves_existing_membership_evidence(
    tmp_path: Path,
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    profile = tmp_path / "profile"
    data_root = profile / "data/customers/customer_001"
    profile.mkdir(mode=0o700)
    data_root.mkdir(mode=0o700, parents=True)
    evidence = tmp_path / "membership.json"
    _ = evidence.write_text("original evidence", encoding="utf-8")
    evidence.chmod(0o600)
    checklist = tmp_path / "checklist.json"
    _ = checklist.write_text("{}", encoding="utf-8")
    deployment = tmp_path / "deployment.json"
    _ = deployment.write_text("{}", encoding="utf-8")
    pin = tmp_path / "pin.json"
    _ = pin.write_text("{}", encoding="utf-8")
    preflight = AsyncMock(
        side_effect=AssertionError("replay must not replace evidence"),
    )
    cutover = Mock(
        return_value=SimpleNamespace(
            to_dict=lambda: {
                "customer_id": "customer_001",
                "state": "ACTIVE",
            }
        )
    )
    monkeypatch.setattr(dualcoach_admin, "staff_membership_preflight", preflight)
    monkeypatch.setattr(
        authority_module,
        "FileCandidateAuthoritySource",
        _FakeAuthoritySource,
    )
    monkeypatch.setattr(cutover_module, "activate_customer_cutover", cutover)

    exit_code = dualcoach_admin.main((
        "customer",
        "activate",
        "--profile-root",
        str(profile),
        "--data-root",
        str(data_root),
        "--customer-id",
        "customer_001",
        "--checklist-evidence",
        str(checklist),
        "--staff-membership-evidence",
        str(evidence),
        "--deployment-receipt",
        str(deployment),
        "--bootstrap-session",
        "cb_session",
        "--expected-generation",
        "7",
        "--task26-authority-pin",
        str(pin),
        "--task26-candidate-digest",
        "a" * 64,
    ))

    assert exit_code == 0
    assert evidence.read_text(encoding="utf-8") == "original evidence"
    preflight.assert_not_awaited()
    cutover.assert_called_once()
