"""
Tests for the candidate exploration system.

Tests cover:
- BaseCandidateExplorer search execution
- Exploration time and candidate limits
- Query generation and result handling
"""

import time
from unittest.mock import Mock


class TestBaseCandidateExplorer:
    """Tests for the BaseCandidateExplorer class."""

    def test_base_explorer_execute_search_list_results(self):
        """Test _execute_search with list results."""
        from src.local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            BaseCandidateExplorer,
        )

        # Create a concrete implementation for testing
        class TestExplorer(BaseCandidateExplorer):
            def explore(
                self, initial_query, constraints=None, entity_type=None
            ):
                pass

            def generate_exploration_queries(
                self, base_query, found_candidates, constraints=None
            ):
                return []

        mock_model = Mock()
        mock_search = Mock()
        mock_search.run.return_value = [
            {"title": "Result 1", "snippet": "Snippet 1"},
            {"title": "Result 2", "snippet": "Snippet 2"},
        ]

        explorer = TestExplorer(
            model=mock_model,
            search_engine=mock_search,
            max_candidates=50,
            max_search_time=60.0,
        )

        result = explorer._execute_search("test query")

        assert "results" in result
        assert len(result["results"]) == 2
        assert result["query"] == "test query"

    def test_base_explorer_execute_search_dict_results(self):
        """Test _execute_search with dict results."""
        from src.local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            BaseCandidateExplorer,
        )

        class TestExplorer(BaseCandidateExplorer):
            def explore(
                self, initial_query, constraints=None, entity_type=None
            ):
                pass

            def generate_exploration_queries(
                self, base_query, found_candidates, constraints=None
            ):
                return []

        mock_model = Mock()
        mock_search = Mock()
        mock_search.run.return_value = {
            "results": [
                {"title": "Result 1", "snippet": "Snippet 1"},
            ],
            "total": 1,
        }

        explorer = TestExplorer(
            model=mock_model,
            search_engine=mock_search,
        )

        result = explorer._execute_search("test query")

        assert "results" in result
        assert len(result["results"]) == 1

    def test_base_explorer_should_continue_time_limit(self):
        """Test exploration stops at time limit."""
        from src.local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            BaseCandidateExplorer,
        )

        class TestExplorer(BaseCandidateExplorer):
            def explore(
                self, initial_query, constraints=None, entity_type=None
            ):
                pass

            def generate_exploration_queries(
                self, base_query, found_candidates, constraints=None
            ):
                return []

        mock_model = Mock()
        mock_search = Mock()

        explorer = TestExplorer(
            model=mock_model,
            search_engine=mock_search,
            max_candidates=100,
            max_search_time=1.0,  # 1 second limit
        )

        start_time = time.time() - 2.0  # Simulate 2 seconds elapsed

        result = explorer._should_continue_exploration(start_time, 0)

        assert result is False  # Should stop due to time limit

    def test_base_explorer_should_continue_candidate_limit(self):
        """Test exploration stops at max candidates."""
        from src.local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            BaseCandidateExplorer,
        )

        class TestExplorer(BaseCandidateExplorer):
            def explore(
                self, initial_query, constraints=None, entity_type=None
            ):
                pass

            def generate_exploration_queries(
                self, base_query, found_candidates, constraints=None
            ):
                return []

        mock_model = Mock()
        mock_search = Mock()

        explorer = TestExplorer(
            model=mock_model,
            search_engine=mock_search,
            max_candidates=10,
            max_search_time=60.0,
        )

        start_time = time.time()  # Just started

        result = explorer._should_continue_exploration(start_time, 15)

        assert result is False  # Should stop due to candidate limit

    def test_base_explorer_deduplicate_candidates(self):
        """Test candidate deduplication."""
        from src.local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            BaseCandidateExplorer,
        )
        from src.local_deep_research.advanced_search_system.candidates.base_candidate import (
            Candidate,
        )

        class TestExplorer(BaseCandidateExplorer):
            def explore(
                self, initial_query, constraints=None, entity_type=None
            ):
                pass

            def generate_exploration_queries(
                self, base_query, found_candidates, constraints=None
            ):
                return []

        mock_model = Mock()
        mock_search = Mock()

        explorer = TestExplorer(
            model=mock_model,
            search_engine=mock_search,
        )

        candidates = [
            Candidate(name="Apple Inc"),
            Candidate(name="apple inc"),  # Duplicate (case insensitive)
            Candidate(name="Google"),
            Candidate(name="  google  "),  # Duplicate (with whitespace)
            Candidate(name="Microsoft"),
        ]

        unique = explorer._deduplicate_candidates(candidates)

        assert len(unique) == 3  # Only Apple, Google, Microsoft

    def test_base_explorer_rank_candidates_by_relevance(self):
        """Test candidate ranking."""
        from src.local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            BaseCandidateExplorer,
        )
        from src.local_deep_research.advanced_search_system.candidates.base_candidate import (
            Candidate,
        )

        class TestExplorer(BaseCandidateExplorer):
            def explore(
                self, initial_query, constraints=None, entity_type=None
            ):
                pass

            def generate_exploration_queries(
                self, base_query, found_candidates, constraints=None
            ):
                return []

        mock_model = Mock()
        mock_search = Mock()

        explorer = TestExplorer(
            model=mock_model,
            search_engine=mock_search,
        )

        candidates = [
            Candidate(
                name="Random Thing", metadata={"query": "unrelated search"}
            ),
            Candidate(
                name="Python Language", metadata={"query": "python programming"}
            ),
        ]

        ranked = explorer._rank_candidates_by_relevance(
            candidates, "python programming"
        )

        # The candidate with matching query words should rank higher
        assert ranked[0].name == "Python Language"

    def test_base_explorer_extract_entity_names_empty(self):
        """Test entity name extraction with empty text."""
        from src.local_deep_research.advanced_search_system.candidate_exploration.base_explorer import (
            BaseCandidateExplorer,
        )

        class TestExplorer(BaseCandidateExplorer):
            def explore(
                self, initial_query, constraints=None, entity_type=None
            ):
                pass

            def generate_exploration_queries(
                self, base_query, found_candidates, constraints=None
            ):
                return []

        mock_model = Mock()
        mock_search = Mock()

        explorer = TestExplorer(
            model=mock_model,
            search_engine=mock_search,
        )

        # Empty text should return empty list
        names = explorer._extract_entity_names("")
        assert names == []

        names = explorer._extract_entity_names("   ")
        assert names == []
