"""ORCH-019 — Quality-Gate invariants on the bug-fast-track (root invariant NFR-1).

Covers (04-test-plan.yaml):
  TC-07  The QG_CHECKS registry + the check_* signatures are NOT changed by the
         bug-fast-track; the machine verdict-keys (verdict / result / deploy_status /
         staging_status / security_status / coverage_status) are preserved by name
         and case.
  TC-12  check_analysis_complete does NOT special-case the bug track (ADR-001 D4):
         a bug lite-package that still emits all 4 analysis files passes; the same
         requirement holds for a non-bug task (no false block, no weakening).
"""
import os
import tempfile

os.environ.setdefault(
    "ORCH_DB_PATH", os.path.join(tempfile.gettempdir(), "test_bft_gates.db")
)
os.environ.setdefault("ORCH_GITEA_TOKEN", "test-token")
os.environ.setdefault("ORCH_PLANE_API_TOKEN", "test-token")

from src.qg.checks import QG_CHECKS, check_analysis_complete  # noqa: E402


# --- TC-07: registry + verdict-keys unchanged ------------------------------
def test_tc07_qg_checks_registry_unchanged():
    # The exact registered gate set — a bug-fast-track must add/remove NOTHING.
    expected = {
        "check_analysis_complete",
        "check_analysis_approved",
        "check_architecture_done",
        "check_ci_green",
        "check_review_approved",
        "check_reviewer_verdict",
        "check_tests_local",
        "check_tests_passed",
        "check_staging_status",
        "check_staging_image_fresh",
        "check_deploy_status",
        "check_branch_mergeable",
        "check_security_gate",
        "check_coverage_gate",
    }
    assert set(QG_CHECKS.keys()) == expected


def test_tc07_verdict_keys_preserved():
    """The frontmatter machine verdict-keys are parsed by exact name/case. ORCH-019
    touches none of the parsers, so the literal keys must still be present."""
    import inspect
    from src.qg import checks as checks_mod
    src = inspect.getsource(checks_mod)
    for key in ("verdict:", "result:", "deploy_status:", "staging_status:"):
        assert key in src, f"verdict key '{key}' must be preserved in qg.checks"
    # security_status / coverage_status live in their own leaves but are read via
    # the same unified frontmatter contract — assert they survive there.
    import inspect as _i
    from src import security_gate, coverage_gate
    assert "security_status" in _i.getsource(security_gate)
    assert "coverage_status" in _i.getsource(coverage_gate)


# --- TC-12: analysis gate not weakened, no false block ---------------------
def _seed_analysis_docs(repo_root, work_item_id, files):
    d = os.path.join(repo_root, "docs", "work-items", work_item_id)
    os.makedirs(d, exist_ok=True)
    for fn in files:
        with open(os.path.join(d, fn), "w") as fh:
            fh.write("stub\n")


def test_tc12_bug_lite_package_with_all_four_passes(monkeypatch, tmp_path):
    from src.qg import checks as checks_mod
    monkeypatch.setattr(checks_mod, "_repo_path", lambda repo, branch=None: str(tmp_path))
    _seed_analysis_docs(
        str(tmp_path), "ORCH-bug",
        ["01-brd.md", "02-trz.md", "03-acceptance-criteria.md", "04-test-plan.yaml"],
    )
    ok, reason = check_analysis_complete("orchestrator", "ORCH-bug", "feature/x")
    assert ok is True, reason


def test_tc12_missing_file_still_fails_for_any_track(monkeypatch, tmp_path):
    """The gate is NOT weakened for bugs: a package missing 02/03 still fails —
    exactly as for a non-bug task (the gate never reads tasks.track)."""
    from src.qg import checks as checks_mod
    monkeypatch.setattr(checks_mod, "_repo_path", lambda repo, branch=None: str(tmp_path))
    _seed_analysis_docs(str(tmp_path), "ORCH-bug", ["01-brd.md", "04-test-plan.yaml"])
    ok, reason = check_analysis_complete("orchestrator", "ORCH-bug", "feature/x")
    assert ok is False
    assert "02-trz.md" in reason and "03-acceptance-criteria.md" in reason


def test_tc12_signature_has_no_track_param():
    import inspect
    params = list(inspect.signature(check_analysis_complete).parameters)
    # byte-for-byte signature: (repo, work_item_id, branch=None) — no track-awareness.
    assert params == ["repo", "work_item_id", "branch"]
