"""Documentation acceptance for the stable control runtime ADR (#615 / PR #616).

Enforces review 443 remediation:

* F1 — operator guide / runbooks cross-link the ADR (issue #615 AC2).
* F2 — LLM sessions are not instructed to kill/restart/relaunch MCP; process
  restart is operator-owned; ADR is the authoritative split.
* F3 — routine post-merge master-parity staleness has a sanctioned response
  (stop → report → operator reload → re-verify parity) and is not a full
  promotion ledger requirement.
"""
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parent.parent
ADR = (
    REPO_ROOT
    / "docs"
    / "architecture"
    / "mcp-stable-control-runtime-policy-adr.md"
)
ADR_REL = "architecture/mcp-stable-control-runtime-policy-adr.md"
ADR_BASENAME = "mcp-stable-control-runtime-policy-adr.md"

CROSS_LINK_DOCS = (
    REPO_ROOT / "docs" / "wiki" / "Operator-Guide.md",
    REPO_ROOT / "docs" / "wiki" / "Runbooks.md",
    REPO_ROOT / "docs" / "llm-workflow-runbooks.md",
)


def _read(path: Path) -> str:
    assert path.is_file(), f"missing {path.relative_to(REPO_ROOT)}"
    return path.read_text(encoding="utf-8")


def test_adr_exists_with_policy_core():
    text = _read(ADR)
    assert text.lstrip().startswith("#"), "ADR lacks a title"
    assert "#615" in text
    assert "stable control runtime" in text.lower()
    assert "2.3" in text and "2.4" in text and "2.5" in text and "2.6" in text


def test_f1_operator_docs_cross_link_adr():
    for path in CROSS_LINK_DOCS:
        text = _read(path)
        assert ADR_BASENAME in text, (
            f"{path.relative_to(REPO_ROOT)} must cross-link {ADR_BASENAME} "
            f"(issue #615 acceptance criterion 2)"
        )


def test_f1_adr_lists_cross_links_as_acceptance_not_optional_tooling():
    text = _read(ADR)
    # Acceptance section must require guide/runbook cross-links.
    assert "Operator guide / runbooks cross-link" in text or (
        "operator guide" in text.lower() and "cross-link" in text.lower()
        and "Acceptance" in text
    )
    # Cross-link must not remain only as optional tooling item #4.
    optional = text.split("## 5. Implementation follow-ups", 1)[-1].split(
        "## 6. Acceptance", 1
    )[0]
    assert "Operator Guide wiki cross-link to this ADR" not in optional, (
        "ADR §5 must not list operator-guide cross-link as optional tooling"
    )
    assert "Not optional" in text or "must** cross-link" in text.lower() or (
        "must cross-link" in text.lower()
    )


def test_f2_runbook_fallback_is_operator_owned_not_llm_restart():
    runbooks = _read(REPO_ROOT / "docs" / "llm-workflow-runbooks.md")
    # Forbidden historical self-service instruction.
    forbidden = (
        "the LLM must relaunch or restart the client/MCP with the correct "
        "profile environment variable before claiming or working on any tasks"
    )
    assert forbidden not in runbooks, (
        "llm-workflow-runbooks must not instruct the LLM to relaunch/restart MCP"
    )
    assert "operator-owned" in runbooks.lower() or "Operator-owned" in runbooks
    assert ADR_BASENAME in runbooks


def test_f2_workspace_rebind_does_not_require_llm_process_relaunch():
    runbooks = _read(REPO_ROOT / "docs" / "llm-workflow-runbooks.md")
    section = runbooks.split("### Safe reconnect / rebind procedure", 1)[-1]
    section = section.split("## Safety notes", 1)[0]
    # Must not tell the LLM alone to relaunch the MCP process as step 2.
    assert "Reconnect or relaunch the correct namespace MCP server from the intended" not in section
    assert "Operator-owned" in section or "operator" in section.lower()
    assert "worktree_path" in section
    collapsed = " ".join(section.lower().split())
    assert "client reconnect" in collapsed


def test_f2_adr_forbids_llm_restart_and_supersedes_self_service_relaunch():
    text = _read(ADR)
    lower = text.lower()
    assert "must not" in lower and "restart" in lower
    assert "operator" in lower and "reload" in lower
    assert "supersedes" in lower
    assert "llm" in lower


def test_f3_adr_defines_post_merge_parity_staleness_response():
    text = _read(ADR)
    lower = text.lower()
    assert "2.6" in text
    assert "post-merge" in lower or "post merge" in lower
    assert "parity" in lower and "stale" in lower
    # Sanctioned steps: stop, report, operator reload, re-verify.
    assert "stop" in lower
    assert "report" in lower
    assert "operator" in lower
    assert "parity is verified" in lower or "re-verif" in lower or (
        "startup/current-head" in lower
    )
    # Not a full promotion ledger for routine reload.
    assert "not a §2.4 promotion" in lower or "not a section 2.4 promotion" in lower or (
        "not a §2.4" in text or "Not a §2.4 promotion" in text
    )
    # Stale parity listed among unhealthy triggers.
    assert "master parity is stale" in lower or "stale master parity" in lower


def test_f3_adr_forbids_llm_bypass_of_parity_gate():
    text = _read(ADR)
    lower = text.lower()
    assert "bypass" in lower or "self-reset" in lower or "self-service" in lower
    assert "parity" in lower


def test_cross_links_do_not_embed_secrets_or_raw_hosts_in_wiki_snippets():
    for path in CROSS_LINK_DOCS:
        text = _read(path)
        for marker in ("ghp_", "BEGIN PRIVATE KEY", "Authorization: Bearer"):
            assert marker not in text, f"{path} contains {marker!r}"
