"""
High-value tests for EvidenceRequirements - pure logic, no mocking needed.

Tests get_requirements() and get_minimum_confidence() static methods
across all ConstraintType values and edge cases.
"""

import pytest

from local_deep_research.advanced_search_system.constraints.base_constraint import (
    ConstraintType,
)
from local_deep_research.advanced_search_system.evidence.requirements import (
    EvidenceRequirements,
)

REQUIRED_KEYS = {"preferred", "acceptable", "sources"}
ALL_CONSTRAINT_TYPES = list(ConstraintType)


# ---------------------------------------------------------------------------
# get_requirements: structural tests for all 8 constraint types
# ---------------------------------------------------------------------------


class TestGetRequirementsStructure:
    """Every ConstraintType should return a dict with the correct keys and non-empty lists."""

    @pytest.mark.parametrize("ctype", ALL_CONSTRAINT_TYPES)
    def test_returns_dict_with_required_keys(self, ctype: ConstraintType):
        result = EvidenceRequirements.get_requirements(ctype)
        assert isinstance(result, dict)
        assert set(result.keys()) == REQUIRED_KEYS

    @pytest.mark.parametrize("ctype", ALL_CONSTRAINT_TYPES)
    def test_preferred_is_non_empty_list(self, ctype: ConstraintType):
        result = EvidenceRequirements.get_requirements(ctype)
        assert isinstance(result["preferred"], list)
        assert len(result["preferred"]) > 0

    @pytest.mark.parametrize("ctype", ALL_CONSTRAINT_TYPES)
    def test_acceptable_is_non_empty_list(self, ctype: ConstraintType):
        result = EvidenceRequirements.get_requirements(ctype)
        assert isinstance(result["acceptable"], list)
        assert len(result["acceptable"]) > 0

    @pytest.mark.parametrize("ctype", ALL_CONSTRAINT_TYPES)
    def test_sources_is_non_empty_list(self, ctype: ConstraintType):
        result = EvidenceRequirements.get_requirements(ctype)
        assert isinstance(result["sources"], list)
        assert len(result["sources"]) > 0


# ---------------------------------------------------------------------------
# get_requirements: specific preferred evidence per type
# ---------------------------------------------------------------------------


class TestGetRequirementsPreferred:
    """Verify the expected preferred evidence types for key constraint types."""

    def test_property_has_direct_statement_preferred(self):
        result = EvidenceRequirements.get_requirements(ConstraintType.PROPERTY)
        assert "direct_statement" in result["preferred"]

    def test_property_has_official_record_preferred(self):
        result = EvidenceRequirements.get_requirements(ConstraintType.PROPERTY)
        assert "official_record" in result["preferred"]

    def test_name_pattern_has_linguistic_analysis_preferred(self):
        result = EvidenceRequirements.get_requirements(
            ConstraintType.NAME_PATTERN
        )
        assert "linguistic_analysis" in result["preferred"]

    def test_event_has_news_report_preferred(self):
        result = EvidenceRequirements.get_requirements(ConstraintType.EVENT)
        assert "news_report" in result["preferred"]

    def test_statistic_has_statistical_data_preferred(self):
        result = EvidenceRequirements.get_requirements(ConstraintType.STATISTIC)
        assert "statistical_data" in result["preferred"]

    def test_temporal_has_official_record_preferred(self):
        result = EvidenceRequirements.get_requirements(ConstraintType.TEMPORAL)
        assert "official_record" in result["preferred"]

    def test_location_has_geographical_data_preferred(self):
        result = EvidenceRequirements.get_requirements(ConstraintType.LOCATION)
        assert "geographical_data" in result["preferred"]

    def test_comparison_has_statistical_comparison_preferred(self):
        result = EvidenceRequirements.get_requirements(
            ConstraintType.COMPARISON
        )
        assert "statistical_comparison" in result["preferred"]

    def test_existence_has_direct_statement_preferred(self):
        result = EvidenceRequirements.get_requirements(ConstraintType.EXISTENCE)
        assert "direct_statement" in result["preferred"]


# ---------------------------------------------------------------------------
# get_requirements: default / unknown type fallback
# ---------------------------------------------------------------------------


class TestGetRequirementsDefault:
    """An unrecognized constraint type should fall back to a safe default."""

    def test_unknown_type_returns_dict_with_required_keys(self):
        fake_type = "not_a_real_type"
        result = EvidenceRequirements.get_requirements(fake_type)
        assert set(result.keys()) == REQUIRED_KEYS

    def test_unknown_type_preferred_is_direct_statement(self):
        fake_type = "not_a_real_type"
        result = EvidenceRequirements.get_requirements(fake_type)
        assert result["preferred"] == ["direct_statement"]

    def test_unknown_type_acceptable_is_inference(self):
        fake_type = "not_a_real_type"
        result = EvidenceRequirements.get_requirements(fake_type)
        assert result["acceptable"] == ["inference"]

    def test_unknown_type_sources_is_general(self):
        fake_type = "not_a_real_type"
        result = EvidenceRequirements.get_requirements(fake_type)
        assert result["sources"] == ["general sources"]


# ---------------------------------------------------------------------------
# get_minimum_confidence: explicit thresholds
# ---------------------------------------------------------------------------


class TestGetMinimumConfidence:
    """Verify the explicit confidence thresholds for mapped types."""

    def test_statistic_confidence_is_0_8(self):
        assert (
            EvidenceRequirements.get_minimum_confidence(
                ConstraintType.STATISTIC
            )
            == 0.8
        )

    def test_event_confidence_is_0_7(self):
        assert (
            EvidenceRequirements.get_minimum_confidence(ConstraintType.EVENT)
            == 0.7
        )

    def test_property_confidence_is_0_6(self):
        assert (
            EvidenceRequirements.get_minimum_confidence(ConstraintType.PROPERTY)
            == 0.6
        )

    def test_name_pattern_confidence_is_0_5(self):
        assert (
            EvidenceRequirements.get_minimum_confidence(
                ConstraintType.NAME_PATTERN
            )
            == 0.5
        )


# ---------------------------------------------------------------------------
# get_minimum_confidence: default threshold for unmapped types
# ---------------------------------------------------------------------------


class TestGetMinimumConfidenceDefault:
    """Types not in the explicit threshold map should return the default 0.6."""

    @pytest.mark.parametrize(
        "ctype",
        [
            ConstraintType.TEMPORAL,
            ConstraintType.LOCATION,
            ConstraintType.COMPARISON,
            ConstraintType.EXISTENCE,
        ],
    )
    def test_unmapped_type_returns_default_0_6(self, ctype: ConstraintType):
        assert EvidenceRequirements.get_minimum_confidence(ctype) == 0.6
