"""
Pure-logic tests for EntityAwareSourceStrategy._format_search_results_as_context.

Tests entity extraction (capitalized words), context window, deduplication,
empty input, and potential-entity-mentions cap — no LLM or search calls.
"""

from unittest.mock import Mock

from local_deep_research.advanced_search_system.strategies.entity_aware_source_strategy import (
    EntityAwareSourceStrategy,
)


def _make_strategy():
    """Build a minimal Mock with attributes used by _format_search_results_as_context."""
    s = Mock(spec=[])
    return s


# ---------------------------------------------------------------------------
# _format_search_results_as_context
# ---------------------------------------------------------------------------


class TestFormatSearchResultsAsContext:
    """Verify entity extraction and context formatting."""

    def test_empty_results(self):
        """Empty results list returns empty string."""
        s = _make_strategy()
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, []
        )
        assert result == ""

    def test_single_result_with_snippet(self):
        """Single result formats title, URL, and snippet."""
        s = _make_strategy()
        results = [
            {
                "title": "About Mountains",
                "snippet": "Mount Rainier is a volcano",
                "link": "https://example.com",
            }
        ]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        assert "About Mountains" in result
        assert "https://example.com" in result
        assert "Mount Rainier is a volcano" in result

    def test_extracts_capitalized_entities(self):
        """Capitalized words > 2 chars are extracted as entity mentions."""
        s = _make_strategy()
        results = [
            {
                "title": "Test",
                "snippet": "Alice visited Paris last summer",
                "link": "",
            }
        ]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        assert "Potential Entity Mentions" in result
        # "Alice" and "Paris" are capitalized and > 2 chars
        assert "Alice" in result
        assert "Paris" in result

    def test_short_capitalized_words_excluded(self):
        """Capitalized words <= 2 chars are not extracted as entities."""
        s = _make_strategy()
        results = [
            {
                "title": "Test",
                "snippet": "Al is here An ox",
                "link": "",
            }
        ]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        # "Al" and "An" are <= 2 chars, should not be in entity mentions
        if "Potential Entity Mentions" in result:
            # Check they're not listed as entities (they may appear in the snippet)
            entity_section = result.split("Potential Entity Mentions")[1]
            assert "- Al " not in entity_section
            assert "- An " not in entity_section

    def test_entity_mentions_capped_at_ten(self):
        """At most 10 entity mentions are included."""
        s = _make_strategy()
        # Create a snippet with many capitalized words
        words = [f"Entity{i}" for i in range(20)]
        snippet = " ".join(words)
        results = [{"title": "Test", "snippet": snippet, "link": ""}]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        entity_section = result.split("Potential Entity Mentions")[1]
        # Count the "- " list items
        mentions = [
            line for line in entity_section.split("\n") if line.startswith("- ")
        ]
        assert len(mentions) <= 10

    def test_no_snippet_excluded(self):
        """Results without snippets are excluded from context."""
        s = _make_strategy()
        results = [{"title": "No Snippet", "snippet": "", "link": ""}]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        assert "Source 1" not in result

    def test_no_entity_mentions_section_when_none_found(self):
        """No entity mentions section when no capitalized words found."""
        s = _make_strategy()
        results = [
            {
                "title": "Test",
                "snippet": "all lowercase words here",
                "link": "",
            }
        ]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        assert "Potential Entity Mentions" not in result

    def test_deduplication_of_entity_contexts(self):
        """Duplicate entity contexts are not repeated."""
        s = _make_strategy()
        results = [
            {
                "title": "Test",
                "snippet": "Alice walked. Alice walked again",
                "link": "",
            }
        ]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        if "Potential Entity Mentions" in result:
            entity_section = result.split("Potential Entity Mentions")[1]
            mentions = [
                line.strip()
                for line in entity_section.split("\n")
                if line.startswith("- ")
            ]
            # Should have unique mentions only
            assert len(mentions) == len(set(mentions))

    def test_multiple_results(self):
        """Multiple results each get a Source N header."""
        s = _make_strategy()
        results = [
            {"title": "First", "snippet": "content one", "link": "url1"},
            {"title": "Second", "snippet": "content two", "link": "url2"},
        ]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        assert "Source 1" in result
        assert "Source 2" in result

    def test_missing_title_uses_untitled(self):
        """Missing title defaults to 'Untitled'."""
        s = _make_strategy()
        results = [{"snippet": "some content", "link": "url"}]
        result = EntityAwareSourceStrategy._format_search_results_as_context(
            s, results
        )
        assert "Untitled" in result
