"""ORCH-110 TC-03: classify_retest_failure distinguishes infra-timeout from red.

Covers D2 (FR-1 / AC-2): the pure predicate that lets the engine route an INFRA
re-test timeout differently from a deterministically RED re-test, WITHOUT changing
the name / PASS-FAIL semantics of the registered ``check_branch_mergeable``.

The critical scope guard: an ``auto_rebase_onto_main`` "rebase timeout" is a
DIFFERENT timeout (git hung) and must NOT be classified as the infra-tolerated
re-test timeout (it stays on the rollback path).
"""
import os
import tempfile

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

import pytest  # noqa: E402

from src import merge_gate  # noqa: E402

classify = merge_gate.classify_retest_failure


@pytest.mark.parametrize(
    "reason,expected",
    [
        ("re-test timeout after 900s", "timeout"),
        ("re-test timeout after 600s", "timeout"),
        ("re-test failed after rebase: 1 failed, 5 passed", "red"),
        ("re-test failed: ...AssertionError\n1 failed", "red"),
        ("merge-lock busy", "lock-busy"),
        ("rebase conflict: src/db.py", "other"),
        # SCOPE GUARD: a git "rebase timeout" is NOT the infra-tolerated re-test
        # timeout — it must stay on the rollback path (ADR D2).
        ("rebase timeout", "other"),
        ("push --force-with-lease failed: ...", "other"),
        ("", "other"),
    ],
)
def test_tc03_classify_reasons(reason, expected):
    assert classify(reason) == expected


def test_tc03_classify_never_raises_on_bad_input():
    # None / non-str must degrade to the safe "other" (-> rollback), never raise.
    assert classify(None) == "other"
    assert classify(12345) == "other"


def test_tc03_case_insensitive():
    assert classify("RE-TEST TIMEOUT AFTER 900S") == "timeout"
    assert classify("Merge-Lock Busy") == "lock-busy"


def test_tc03_distinct_from_lock_busy_and_conflict():
    """timeout is a distinct class from the existing defer (lock-busy) and rollback
    (conflict) reasons — the three must never collide."""
    classes = {
        classify("re-test timeout after 900s"),
        classify("merge-lock busy"),
        classify("rebase conflict: x"),
    }
    assert classes == {"timeout", "lock-busy", "other"}
