"""Doc-contract checks for subagent tool-budget guardrails (#259).

Single-step MCP tasks must not expand into 100+ tool-call retry spirals with
WebFetch/Playwright/manual-encoding fallbacks. These tests pin budget defaults,
native-MCP-first rules, and forbidden detours in the runbooks, portable skill,
and operator guide.
"""
from pathlib import Path

REPO_ROOT = Path(__file__).resolve().parent.parent

RUNBOOK = REPO_ROOT / "docs" / "llm-workflow-runbooks.md"
SKILL = REPO_ROOT / "skills" / "llm-project-workflow" / "SKILL.md"


def _normalize(text: str) -> str:
    """Collapse whitespace so phrase checks survive markdown line wrapping."""
    return " ".join(text.split())


def _runbook_text() -> str:
    return _normalize(RUNBOOK.read_text(encoding="utf-8"))


def _skill_text() -> str:
    return _normalize(SKILL.read_text(encoding="utf-8"))


def test_runbook_has_subagent_tool_budget_section():
    text = _runbook_text()
    assert "## Subagent Tool-Budget Guardrails" in text
    for phrase in (
        "15",
        "5 minutes",
        "40",
        "15 minutes",
        "gitea_commit_files",
        "WebFetch",
        "Playwright",
        "no retry spirals",
    ):
        assert phrase.lower() in text.lower(), f"runbook missing phrase: {phrase!r}"


def test_runbook_forbids_subagent_commit_delegation():
    text = _runbook_text()
    for phrase in (
        "do not delegate commit authority to a subagent",
        "main session first",
        "native MCP before fallback",
    ):
        assert phrase.lower() in text.lower(), f"runbook missing: {phrase!r}"


def test_runbook_rejects_fallback_detours_when_mcp_commit_available():
    lower = _runbook_text().lower()
    for forbidden in ("webfetch", "playwright", "manual llm-generated base64"):
        assert forbidden in lower, f"runbook must name forbidden detour: {forbidden!r}"
    assert "_encode_" in lower
    assert "gitea_commit_files" in lower


def test_skill_doc_declares_subagent_tool_budget_guardrails():
    text = _skill_text()
    assert "## Subagent Tool-Budget Guardrails" in text
    for phrase in (
        "15 tool calls",
        "5 minutes",
        "gitea_commit_files",
        "WebFetch",
        "never resume a failed subagent",
    ):
        assert phrase.lower() in text.lower(), f"SKILL.md missing phrase: {phrase!r}"


def test_operator_guide_rules_include_subagent_tool_budget():
    import sys

    sys.path.insert(0, str(REPO_ROOT))
    import gitea_mcp_server

    rule = gitea_mcp_server._GUIDE_RULES["subagent_tool_budget"]
    for phrase in (
        "15 tool calls",
        "gitea_commit_files",
        "WebFetch",
        "retry loop",
    ):
        assert phrase in rule, f"operator guide rule missing: {phrase!r}"