"""Tests for cortex.extraction.predicate_filter."""
import pytest
from cortex.extraction.predicate_filter import filter_claims, cap_engineering_claims


class TestFilterClaims:
    def test_blocked_predicate_removed(self):
        claims = [
            {"subject": "Eva", "predicate": "implements", "object_value": "filter"},
            {"subject": "Andrew", "predicate": "prefers", "object_value": "Python"},
        ]
        result = filter_claims(claims)
        assert len(result) == 1
        assert result[0]["predicate"] == "prefers"

    def test_allowed_predicate_passes(self):
        claims = [
            {"subject": "Andrew", "predicate": "prefers", "object_value": "Python"},
            {"subject": "Andrew", "predicate": "uses", "object_value": "VS Code"},
        ]
        result = filter_claims(claims)
        assert len(result) == 2

    def test_blocked_subject_removed(self):
        claims = [
            {"subject": "R-017", "predicate": "prefers", "object_value": "stuff"},
            {"subject": "CodeRabbit", "predicate": "likes", "object_value": "stuff"},
            {"subject": "Sonnet", "predicate": "is", "object_value": "model"},
            {"subject": "Opus", "predicate": "is", "object_value": "model"},
            {"subject": "Haiku", "predicate": "is", "object_value": "model"},
            {"subject": "Andrew", "predicate": "prefers", "object_value": "Python"},
        ]
        result = filter_claims(claims)
        assert len(result) == 1
        assert result[0]["subject"] == "Andrew"

    def test_tmp_path_in_object_removed(self):
        claims = [
            {"subject": "Eva", "predicate": "prefers", "object_value": "check /tmp/electric-sheep/test.py"},
            {"subject": "Andrew", "predicate": "uses", "object_value": "VS Code"},
        ]
        result = filter_claims(claims)
        assert len(result) == 1
        assert result[0]["subject"] == "Andrew"

    def test_case_insensitive_predicate(self):
        claims = [
            {"subject": "Eva", "predicate": "IMPLEMENTS", "object_value": "filter"},
            {"subject": "Eva", "predicate": "Fixed", "object_value": "bug"},
        ]
        result = filter_claims(claims)
        assert len(result) == 0

    def test_empty_claims(self):
        assert filter_claims([]) == []

    def test_subject_pattern_partial_no_match(self):
        """R-017-extra should NOT be blocked (pattern is exact match)."""
        claims = [
            {"subject": "R-017-extra", "predicate": "prefers", "object_value": "stuff"},
        ]
        result = filter_claims(claims)
        assert len(result) == 1


class TestCapEngineeringClaims:
    def test_under_cap_passes(self):
        claims = [
            {"category": "decisions", "confidence": 0.9, "predicate": "chose"},
            {"category": "personal", "confidence": 0.8, "predicate": "likes"},
        ]
        result = cap_engineering_claims(claims)
        assert len(result) == 2

    def test_over_cap_keeps_highest_confidence(self):
        claims = [
            {"category": "decisions", "confidence": 0.5, "predicate": "a"},
            {"category": "decisions", "confidence": 0.9, "predicate": "b"},
            {"category": "decisions", "confidence": 0.7, "predicate": "c"},
            {"category": "personal", "confidence": 0.8, "predicate": "d"},
        ]
        result = cap_engineering_claims(claims, max_count=2)
        assert len(result) == 3  # 2 engineering + 1 personal
        eng = [c for c in result if c["category"] == "decisions"]
        assert len(eng) == 2
        confs = sorted([c["confidence"] for c in eng])
        assert confs == [0.7, 0.9]

    def test_empty_claims(self):
        assert cap_engineering_claims([]) == []

    def test_no_engineering(self):
        claims = [
            {"category": "personal", "confidence": 0.8, "predicate": "a"},
        ]
        result = cap_engineering_claims(claims)
        assert len(result) == 1


class TestWithDataclasses:
    """Test that filters work with ClaimExtraction dataclass objects."""

    def test_filter_dataclass_objects(self):
        from cortex.extraction.extractor import ClaimExtraction
        claims = [
            ClaimExtraction(
                action="ADD", subject="Eva", predicate="implements",
                object_value="filter", confidence=0.9,
            ),
            ClaimExtraction(
                action="ADD", subject="Andrew", predicate="prefers",
                object_value="Python", confidence=0.9,
            ),
        ]
        result = filter_claims(claims)
        assert len(result) == 1
        assert result[0].predicate == "prefers"

    def test_cap_dataclass_objects(self):
        from cortex.extraction.extractor import ClaimExtraction
        claims = [
            ClaimExtraction(
                action="ADD", subject="Eva", predicate="chose",
                object_value="a", confidence=0.5, category="decisions",
            ),
            ClaimExtraction(
                action="ADD", subject="Eva", predicate="chose",
                object_value="b", confidence=0.9, category="decisions",
            ),
            ClaimExtraction(
                action="ADD", subject="Eva", predicate="chose",
                object_value="c", confidence=0.7, category="decisions",
            ),
            ClaimExtraction(
                action="ADD", subject="Andrew", predicate="prefers",
                object_value="d", confidence=0.8, category="personal",
            ),
        ]
        result = cap_engineering_claims(claims, max_count=2)
        assert len(result) == 3
