# -*- coding: utf-8 -*-
"""task-2673 RS-2670-B regression — poll #12 fresh evidence + new unresolved.

수정 목표 1·4 검증: classify() 가 fresh_gemini_head_match + unresolved>0 + BLOCKED
신호를 만나면 즉시 HOLD_FOR_CHAIR 로 조기 전환한다. 사고 박제 (dev7 watcher.py
poll #12 silent fall-through) 의 재발 방지 결정적 case.
"""
from __future__ import annotations

import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[2]))

import pytest  # noqa: E402

from utils.pr_watcher_terminal_state_classifier import (  # noqa: E402
    HOLD_FOR_CHAIR,
    MERGE_READY,
    PRSnapshot,
    classify,
)


def test_poll_12_returns_hold_for_chair_immediately(
    poll_12_pr_data, poll_12_th_data, expected_head
):
    """RS-2670-B 본체 — poll #12 결정적 시나리오."""
    snap = PRSnapshot.from_gh(poll_12_pr_data, poll_12_th_data)
    state, reason = classify(
        snap,
        elapsed_watcher_sec=1336,
        expected_head=expected_head,
        max_watch_seconds=60 * 60,
    )

    assert state == HOLD_FOR_CHAIR
    assert "fresh_gemini_head_match" in reason
    assert "unresolved=3" in reason
    assert "mss=BLOCKED" in reason


def test_b_pos_merge_ready_not_misfired(
    merge_ready_pr_data, all_resolved_th_data, expected_head
):
    """B-pos — fresh + 0 unresolved + CLEAN 면 MERGE_READY 로 가야 하고
    HOLD_FOR_CHAIR 분기가 발화하면 안 된다."""
    snap = PRSnapshot.from_gh(merge_ready_pr_data, all_resolved_th_data)
    state, _ = classify(
        snap,
        elapsed_watcher_sec=120,
        expected_head=expected_head,
    )
    assert state == MERGE_READY


def test_b_neg_stale_gemini_does_not_trigger_hold(
    poll_12_pr_data, poll_12_th_data, expected_head, stale_gemini_review
):
    """B-neg — gemini_fresh=False 이면 fresh-evidence HOLD 분기 발화 안 함."""
    pr = dict(poll_12_pr_data)
    pr["reviews"] = [stale_gemini_review]
    snap = PRSnapshot.from_gh(pr, poll_12_th_data)
    state, reason = classify(
        snap,
        elapsed_watcher_sec=1336,
        expected_head=expected_head,
        max_watch_seconds=60 * 60,
    )
    # fresh-evidence HOLD 분기 발화하면 안 됨. continue 가 정상 (Gemini stale 분기는
    # head_committed_utc 가 주어졌을 때만; 본 케이스는 미주입 → continue 기대)
    assert state == ""
    assert reason == "continue"


def test_b_edge_blocked_alternative_state_no_hold_fresh_branch(
    poll_12_pr_data, poll_12_th_data, expected_head
):
    """B-edge — mss=BEHIND (BLOCKED 아님) + fresh + unresolved 면 fresh-evidence
    HOLD 분기 발화 안 함 (정책 외)."""
    pr = dict(poll_12_pr_data)
    pr["mergeStateStatus"] = "BEHIND"
    snap = PRSnapshot.from_gh(pr, poll_12_th_data)
    state, _ = classify(
        snap,
        elapsed_watcher_sec=1336,
        expected_head=expected_head,
    )
    assert state == ""


def test_head_drift_returns_hold_for_chair(head_drift_pr_data, expected_head):
    """수정 목표 2 — head drift 도 HOLD_FOR_CHAIR (spec §5 admin override)."""
    snap = PRSnapshot.from_gh(head_drift_pr_data, {})
    state, reason = classify(
        snap,
        elapsed_watcher_sec=60,
        expected_head=expected_head,
    )
    assert state == HOLD_FOR_CHAIR
    assert "head_drift" in reason
    assert "admin override" in reason
