"""
Pure-logic tests for ImprovedEvidenceBasedStrategy._get_adaptive_distinctive_constraints.

Tests priority ordering based on successful patterns, constraint sorting by
type priority and weight, and edge cases — no LLM or search calls.
"""

from unittest.mock import Mock

from local_deep_research.advanced_search_system.constraints.base_constraint import (
    Constraint,
    ConstraintType,
)
from local_deep_research.advanced_search_system.strategies.improved_evidence_based_strategy import (
    ImprovedEvidenceBasedStrategy,
)


def _constraint(cid, ctype, weight=1.0):
    return Constraint(
        id=cid,
        type=ctype,
        description=f"desc_{cid}",
        value=f"val_{cid}",
        weight=weight,
    )


def _make_strategy(constraints=None, successful_patterns=None):
    """Build a minimal Mock for ImprovedEvidenceBasedStrategy."""
    s = Mock(spec=[])
    s.constraints = constraints or []
    s.successful_patterns = successful_patterns or []
    return s


# ---------------------------------------------------------------------------
# _get_adaptive_distinctive_constraints
# ---------------------------------------------------------------------------


class TestGetAdaptiveDistinctiveConstraints:
    """Verify adaptive constraint prioritization."""

    def test_default_priority_order(self):
        """Without successful patterns, uses default priority order."""
        c_prop = _constraint("c1", ConstraintType.PROPERTY)
        c_name = _constraint("c2", ConstraintType.NAME_PATTERN)
        c_event = _constraint("c3", ConstraintType.EVENT)
        s = _make_strategy(constraints=[c_prop, c_name, c_event])
        result = (
            ImprovedEvidenceBasedStrategy._get_adaptive_distinctive_constraints(
                s
            )
        )
        # NAME_PATTERN has highest default priority, then EVENT, then PROPERTY
        assert result[0].type == ConstraintType.NAME_PATTERN
        assert result[1].type == ConstraintType.EVENT

    def test_successful_patterns_reorder_priority(self):
        """Successful patterns boost constraint type priority."""
        c_prop = _constraint("c1", ConstraintType.PROPERTY)
        c_temp = _constraint("c2", ConstraintType.TEMPORAL)
        # Temporal had success
        patterns = [
            {"constraints": ["c2"], "candidates_found": 5},
        ]
        s = _make_strategy(
            constraints=[c_prop, c_temp], successful_patterns=patterns
        )
        result = (
            ImprovedEvidenceBasedStrategy._get_adaptive_distinctive_constraints(
                s
            )
        )
        # TEMPORAL should be boosted above PROPERTY
        assert result[0].type == ConstraintType.TEMPORAL

    def test_weight_tiebreak(self):
        """Equal-priority constraints sorted by weight descending."""
        c1 = _constraint("c1", ConstraintType.PROPERTY, weight=0.5)
        c2 = _constraint("c2", ConstraintType.PROPERTY, weight=0.9)
        s = _make_strategy(constraints=[c1, c2])
        result = (
            ImprovedEvidenceBasedStrategy._get_adaptive_distinctive_constraints(
                s
            )
        )
        assert result[0].weight >= result[1].weight

    def test_empty_constraints(self):
        """Empty constraints returns empty list."""
        s = _make_strategy(constraints=[])
        result = (
            ImprovedEvidenceBasedStrategy._get_adaptive_distinctive_constraints(
                s
            )
        )
        assert result == []

    def test_no_successful_patterns(self):
        """No patterns uses default order."""
        c = _constraint("c1", ConstraintType.EXISTENCE)
        s = _make_strategy(constraints=[c], successful_patterns=[])
        result = (
            ImprovedEvidenceBasedStrategy._get_adaptive_distinctive_constraints(
                s
            )
        )
        assert len(result) == 1

    def test_multiple_patterns_accumulate(self):
        """Multiple successful patterns accumulate candidates_found."""
        c_loc = _constraint("c1", ConstraintType.LOCATION)
        c_stat = _constraint("c2", ConstraintType.STATISTIC)
        patterns = [
            {"constraints": ["c1"], "candidates_found": 3},
            {
                "constraints": ["c1"],
                "candidates_found": 2,
            },  # Total: 5 for LOCATION
            {
                "constraints": ["c2"],
                "candidates_found": 4,
            },  # Total: 4 for STATISTIC
        ]
        s = _make_strategy(
            constraints=[c_loc, c_stat], successful_patterns=patterns
        )
        result = (
            ImprovedEvidenceBasedStrategy._get_adaptive_distinctive_constraints(
                s
            )
        )
        # LOCATION (5) should rank above STATISTIC (4)
        assert result[0].type == ConstraintType.LOCATION

    def test_unknown_constraint_id_in_pattern_ignored(self):
        """Pattern referencing unknown constraint ID is safely ignored."""
        c = _constraint("c1", ConstraintType.PROPERTY)
        patterns = [
            {"constraints": ["c_nonexistent"], "candidates_found": 10},
        ]
        s = _make_strategy(constraints=[c], successful_patterns=patterns)
        result = (
            ImprovedEvidenceBasedStrategy._get_adaptive_distinctive_constraints(
                s
            )
        )
        assert len(result) == 1
