"""ORCH-016 / TC-20 + AC-11: Quality Gates + stage machine are unchanged.

Smoke / change-detector test: the ORCH-016 PR touches comment formatting only.
The QG registry (src/qg/checks.QG_CHECKS) and the stage-machine table
(src/stages.STAGE_TRANSITIONS) MUST remain bit-identical to the contracts the
pipeline depends on. If a future change moves the comment hot path into these
files by accident, this guard breaks first.
"""

import os

os.environ.setdefault("ORCH_PLANE_API_TOKEN", "test-token")
os.environ.setdefault("ORCH_GITEA_TOKEN", "test-token")

from src.qg.checks import QG_CHECKS  # noqa: E402
from src.stages import STAGE_TRANSITIONS  # noqa: E402


# The set of QG names the pipeline DEPLOYS on. Order doesn't matter, identity does.
_EXPECTED_QGS = {
    "check_analysis_approved",
    "check_analysis_complete",
    "check_architecture_done",
    "check_ci_green",
    "check_review_approved",
    "check_tests_passed",
    "check_reviewer_verdict",
    "check_tests_local",
    "check_deploy_status",
    "check_staging_status",
    "check_branch_mergeable",  # ORCH-043 merge-gate (deploy-staging -> deploy edge)
    "check_staging_image_fresh",  # ORCH-058 image-freshness sub-gate (same edge)
    "check_security_gate",  # ORCH-022 security sub-gate (same edge, run FIRST)
}


def test_tc20_qg_registry_unchanged():
    assert set(QG_CHECKS.keys()) == _EXPECTED_QGS


def test_tc20_qg_callables_unchanged():
    # All entries must be callable — no stub / lambda / None.
    for name, fn in QG_CHECKS.items():
        assert callable(fn), f"QG {name} is not callable"


# Reference snapshot of STAGE_TRANSITIONS (mirrors what's in docs/architecture
# and src/stages.py — duplicated here on purpose as a regression yardstick).
_EXPECTED_TRANSITIONS = {
    "created":        {"next": "analysis",        "agent": "analyst",   "qg": None},
    "analysis":       {"next": "architecture",    "agent": "architect", "qg": "check_analysis_approved"},
    "architecture":   {"next": "development",     "agent": "developer", "qg": "check_architecture_done"},
    "development":    {"next": "review",          "agent": "reviewer",  "qg": "check_ci_green"},
    "review":         {"next": "testing",         "agent": "tester",    "qg": "check_reviewer_verdict"},
    "testing":        {"next": "deploy-staging",  "agent": "deployer",  "qg": "check_tests_passed"},
    "deploy-staging": {"next": "deploy",          "agent": "deployer",  "qg": "check_staging_status"},
    "deploy":         {"next": "done",            "agent": None,        "qg": "check_deploy_status"},
    "done":           {"next": None,              "agent": None,        "qg": None},
}


def test_tc20_stage_transitions_unchanged():
    assert STAGE_TRANSITIONS == _EXPECTED_TRANSITIONS, (
        "STAGE_TRANSITIONS drift detected — ORCH-016 must not change the "
        "stage machine. Touched stage_engine or stages.py? Update the snapshot "
        "in a separate, intentional PR."
    )
