"""Tests for diagnostics/activity_endpoint.py classify_pr_operation.

Covers the Leo gotcha — extract/* branches with commit_type=enrich or
challenge classify by commit_type, not branch prefix. Same class of bug
as the contributor-role wiring fix.
"""

import sys
from pathlib import Path

import pytest

# diagnostics/ isn't on sys.path by default; add it for these tests.
_DIAG = Path(__file__).resolve().parents[1] / "diagnostics"
if str(_DIAG) not in sys.path:
    sys.path.insert(0, str(_DIAG))

# aiohttp is imported at module load time; skip cleanly if not installed.
pytest.importorskip("aiohttp")

from activity_endpoint import classify_pr_operation  # noqa: E402


# ─── Merged PRs: commit_type wins over branch prefix ───────────────────────


def test_extract_branch_legacy_knowledge_classifies_new():
    assert classify_pr_operation("merged", "knowledge", "extract/foo", None) == "new"


def test_extract_branch_with_enrich_commit_type_classifies_enrich():
    """Leo gotcha: extract/* + commit_type=enrich → enrich, not new."""
    assert classify_pr_operation("merged", "enrich", "extract/foo", None) == "enrich"


def test_extract_branch_with_challenge_commit_type_classifies_challenge():
    """Leo gotcha: extract/* + commit_type=challenge → challenge, not new."""
    assert classify_pr_operation("merged", "challenge", "extract/foo", None) == "challenge"


def test_challenged_by_in_description_classifies_challenge():
    assert (
        classify_pr_operation(
            "merged", "knowledge", "extract/foo", "evidence for challenged_by claim"
        )
        == "challenge"
    )


# ─── Branch prefix fallback (when commit_type is generic) ──────────────────


def test_reweave_branch_classifies_enrich():
    assert classify_pr_operation("merged", "knowledge", "reweave/batch-1", None) == "enrich"


def test_challenge_branch_classifies_challenge():
    assert (
        classify_pr_operation("merged", "knowledge", "challenge/nuclear-moloch", None)
        == "challenge"
    )


# ─── Maintenance commit_types → infra ──────────────────────────────────────


def test_fix_commit_type_classifies_infra():
    assert classify_pr_operation("merged", "fix", "fix/deploy-bug", None) == "infra"


def test_pipeline_commit_type_classifies_infra():
    assert (
        classify_pr_operation("merged", "pipeline", "epimetheus/migration-v14", None)
        == "infra"
    )


# ─── Knowledge-producing commit_types → new ────────────────────────────────


def test_research_commit_type_classifies_new():
    assert (
        classify_pr_operation("merged", "research", "theseus/cornelius-batch-2", None)
        == "new"
    )


def test_entity_commit_type_classifies_new():
    assert classify_pr_operation("merged", "entity", "leo/entities-update", None) == "new"


# ─── Non-merged statuses route through NON_MERGED_STATUS_TO_OPERATION ──────


def test_open_pr_classifies_extract():
    assert classify_pr_operation("open", None, "extract/foo", None) == "extract"


def test_approved_pr_classifies_new():
    assert classify_pr_operation("approved", None, "extract/foo", None) == "new"


def test_closed_pr_classifies_infra():
    assert classify_pr_operation("closed", None, "extract/foo", None) == "infra"


def test_conflict_pr_classifies_challenge():
    assert classify_pr_operation("conflict", None, "extract/foo", None) == "challenge"


def test_validating_pr_classifies_extract():
    assert classify_pr_operation("validating", None, "extract/foo", None) == "extract"


def test_reviewing_pr_classifies_extract():
    assert classify_pr_operation("reviewing", None, "extract/foo", None) == "extract"


def test_merging_pr_classifies_new():
    assert classify_pr_operation("merging", None, "extract/foo", None) == "new"


def test_zombie_pr_classifies_infra():
    assert classify_pr_operation("zombie", None, "extract/foo", None) == "infra"


# ─── Priority order: reweave commit_type vs reweave/ branch ─────────────────
# Reweave commit_type is in _MAINTENANCE_COMMIT_TYPES (→ infra), but
# branch.startswith('reweave/') is checked first (→ enrich). The bifurcation
# is real spec behavior — nightly reweave PRs must classify as enrich, not
# infra. Locking this in prevents a silent flip on future priority refactors.


def test_reweave_commit_type_with_reweave_branch_classifies_enrich():
    """Branch prefix wins over maintenance — reweave PRs are enrich, not infra."""
    assert classify_pr_operation("merged", "reweave", "reweave/batch-1", None) == "enrich"


def test_reweave_commit_type_without_reweave_branch_classifies_infra():
    """Without reweave/ prefix, reweave commit_type falls to maintenance → infra."""
    assert classify_pr_operation("merged", "reweave", "epimetheus/foo", None) == "infra"


# ─── Defensive cases — null/empty inputs shouldn't crash ───────────────────


def test_null_commit_type_and_branch_classifies_new():
    assert classify_pr_operation("merged", None, None, None) == "new"


def test_unknown_status_falls_back_to_infra():
    assert classify_pr_operation("nonsense", None, None, None) == "infra"
