"""tests/regression/test_batch_hold_adjudication.py

task-2614 Track E — 실제 이번 batch 사례(2604/2605/2608/2609)를 fixture 로
박제하고 Track A ``anu_v3.batch_hold_adjudicator`` 를 **read-only import**
하여 올바른 consolidated 분류가 산출되는지 검증한다(재발 방지).

문서-only/mock-only 금지: 본 regression 은 실 모듈 + 실 entrypoint
(``adjudicate_from_payload``)를 실행한다. 상수 분류기(항상 동일 verdict)는
케이스별 verdict 불일치로 반드시 FAIL 한다(§11 meta-가드).
"""
from __future__ import annotations

import json
import sys
from pathlib import Path

import pytest

WORKSPACE = Path(__file__).resolve().parent.parent.parent
if str(WORKSPACE) not in sys.path:
    sys.path.insert(0, str(WORKSPACE))

import anu_v3.batch_hold_adjudicator as BHA  # noqa: E402
from anu_v3.batch_hold_adjudicator import (  # noqa: E402
    AUTHORITATIVE_PASS,
    AUTO_REMEDIATION_HOLD,
    CHAIR_HOLD,
    WAITING_FOR_DEPENDENCY,
    adjudicate_from_payload,
)

FIXTURES = WORKSPACE / "memory" / "fixtures"
CASES = ("2604", "2605", "2608", "2609")


def _load(case: str) -> dict:
    return json.loads(
        (FIXTURES / f"task-2614.case-{case}.json").read_text(encoding="utf-8")
    )


@pytest.mark.parametrize("case", CASES)
def test_real_case_classification(case: str) -> None:
    fx = _load(case)
    exp = fx["expected"]
    out = adjudicate_from_payload({"tracks": [fx["track_a_input"]]})
    ta = out.tracks[0]
    assert ta.classification == exp["track_a_classification"], (
        case,
        ta.classification,
        ta.reasons,
    )
    assert ta.chair_escalation == exp["track_a_chair_escalation"]
    assert ta.auto_remediation == exp["track_a_auto_remediation"]


def test_consolidated_batch_over_all_four_cases() -> None:
    """4 사례를 하나의 batch 로 모아 consolidated adjudication 검증.

    2604/2605/2609 = AUTO_REMEDIATION_HOLD(non-Critical 자동 수렴),
    2608 = WAITING_FOR_DEPENDENCY. Critical7/shared-invariant 0 →
    chair 보고 0, auto_remediation 수렴, all-settled=False(미정착이나 보고
    불요)."""
    tracks = [_load(c)["track_a_input"] for c in CASES]
    out = adjudicate_from_payload({"tracks": tracks})
    assert out.chair_escalation_required is False
    assert out.critical7_present is False
    assert out.shared_invariant_breach is False
    assert out.auto_remediation_required is True
    assert out.all_settled is False
    counts = out.classification_counts
    assert counts[AUTO_REMEDIATION_HOLD] == 3
    assert counts[WAITING_FOR_DEPENDENCY] == 1


def test_critical7_track_escalates_chair() -> None:
    """Critical7 분류가 입력되면 전체 CHAIR_HOLD 로 격상(회장 §6)."""
    crit = dict(_load("2604")["track_a_input"])
    crit["classifier_is_critical7"] = True
    crit["classifier_category"] = "forbidden_path"
    out = adjudicate_from_payload({"tracks": [crit]})
    assert out.tracks[0].classification == CHAIR_HOLD
    assert out.chair_escalation_required is True
    assert out.verdict == "HOLD_FOR_CHAIR"


def test_independent_anu_pass_is_authoritative_pass() -> None:
    """provable independent-ANU PASS → AUTHORITATIVE_PASS (회장 §5.D)."""
    payload = {
        "tracks": [
            {
                "track_id": "t-pass",
                "task_id": "task-2604",
                "dispatch_received": True,
                "authoritative_verdict": "PASS",
                "authoritative_is_independent_anu": True,
                "collector_key": "c119085addb0f8b7",
                "executor_key": "fedf78d1d09509f5",
                "collector_role": "ANU",
            }
        ]
    }
    out = adjudicate_from_payload(payload)
    assert out.tracks[0].classification == AUTHORITATIVE_PASS


def test_self_chain_pass_fails_closed_not_authoritative() -> None:
    """independent 증명 없는 self-chain PASS 자칭 → HOLD_CANDIDATE."""
    payload = {
        "tracks": [
            {
                "track_id": "t-self",
                "task_id": "task-2605",
                "dispatch_received": True,
                "authoritative_verdict": "PASS",
                "authoritative_is_independent_anu": True,
                "collector_key": "1e41a2324a3ccdd0",
                "executor_key": "1e41a2324a3ccdd0",
                "collector_role": "ANU",
            }
        ]
    }
    out = adjudicate_from_payload(payload)
    assert out.tracks[0].classification != AUTHORITATIVE_PASS


def test_mock_only_would_fail_meta_guard() -> None:
    """실 모듈/실 entrypoint 입증 — 상수 분류기는 케이스별 verdict 불일치로
    반드시 FAIL 한다(mock-only FAIL)."""
    verdicts = {
        c: adjudicate_from_payload(
            {"tracks": [_load(c)["track_a_input"]]}
        ).tracks[0].classification
        for c in CASES
    }
    # 2608 은 WAITING_FOR_DEPENDENCY, 나머지는 AUTO_REMEDIATION_HOLD —
    # 단일 상수 반환 분류기로는 동시에 만족 불가.
    assert len(set(verdicts.values())) >= 2, verdicts
    assert callable(BHA.adjudicate_from_payload)
    assert "MagicMock" not in type(BHA).__name__
