"""
Comprehensive tests for the Brave search engine.
Tests initialization, search functionality, error handling, and result parsing.

Note: These tests mock the BraveSearch dependency to avoid requiring an API key.
"""

import pytest
from unittest.mock import Mock


class TestBraveSearchEngineInit:
    """Tests for Brave search engine initialization."""

    @pytest.fixture(autouse=True)
    def mock_brave_search(self, monkeypatch):
        """Mock BraveSearch to avoid needing an API key."""
        mock_brave = Mock()
        mock_brave.from_api_key = Mock(return_value=mock_brave)
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_brave.BraveSearch",
            mock_brave,
        )
        return mock_brave

    def test_init_with_api_key(self):
        """Test initialization with API key."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(api_key="test_api_key")
        assert engine.max_results >= 10
        assert engine.is_public is True
        assert engine.is_generic is True

    def test_init_custom_max_results(self):
        """Test initialization with custom max results."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(api_key="test_key", max_results=25)
        assert engine.max_results >= 25

    def test_init_with_region(self):
        """Test initialization with specific region."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(api_key="test_key", region="DE")
        # Region is passed to BraveSearch, verify engine was created
        assert engine is not None

    def test_init_with_safe_search(self):
        """Test initialization with safe search options."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(api_key="test_key", safe_search=True)
        assert engine is not None

        engine_unsafe = BraveSearchEngine(api_key="test_key", safe_search=False)
        assert engine_unsafe is not None

    def test_init_without_api_key_raises(self, monkeypatch):
        """Test that initialization without API key raises ValueError."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        # Mock get_setting_from_snapshot to return None
        monkeypatch.setattr(
            "local_deep_research.config.search_config.get_setting_from_snapshot",
            lambda *args, **kwargs: None,
        )

        with pytest.raises(ValueError, match="Brave API key not found"):
            BraveSearchEngine()

    def test_init_with_language_mapping(self):
        """Test initialization with different languages."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(
            api_key="test_key", search_language="Spanish"
        )
        assert engine is not None

        engine_fr = BraveSearchEngine(
            api_key="test_key", search_language="French"
        )
        assert engine_fr is not None


class TestBraveSearchEngineType:
    """Tests for Brave engine type identification."""

    @pytest.fixture(autouse=True)
    def mock_brave_search(self, monkeypatch):
        """Mock BraveSearch to avoid needing an API key."""
        mock_brave = Mock()
        mock_brave.from_api_key = Mock(return_value=mock_brave)
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_brave.BraveSearch",
            mock_brave,
        )

    def test_engine_type_set(self):
        """Test that engine type is properly set."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(api_key="test_key")
        assert "brave" in engine.engine_type.lower()

    def test_engine_is_public(self):
        """Test that engine is marked as public."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(api_key="test_key")
        assert engine.is_public is True

    def test_engine_is_generic(self):
        """Test that engine is marked as generic."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(api_key="test_key")
        assert engine.is_generic is True


class TestBraveSearchExecution:
    """Tests for Brave search execution."""

    @pytest.fixture(autouse=True)
    def mock_brave_search(self, monkeypatch):
        """Mock BraveSearch to avoid needing an API key."""
        self.mock_brave = Mock()
        self.mock_brave.from_api_key = Mock(return_value=self.mock_brave)
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_brave.BraveSearch",
            self.mock_brave,
        )

    def test_get_previews_success(self):
        """Test successful preview retrieval."""
        import json

        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        # Mock the run method to return JSON results
        mock_results = [
            {
                "title": "Test Result 1",
                "link": "https://example1.com",
                "snippet": "Snippet 1",
            },
            {
                "title": "Test Result 2",
                "link": "https://example2.com",
                "snippet": "Snippet 2",
            },
        ]
        self.mock_brave.run = Mock(return_value=json.dumps(mock_results))

        engine = BraveSearchEngine(api_key="test_key")
        previews = engine._get_previews("test query")

        assert len(previews) == 2
        assert previews[0]["title"] == "Test Result 1"
        assert previews[1]["link"] == "https://example2.com"

    def test_get_previews_handles_list_response(self):
        """Test preview retrieval when response is already a list."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        # Mock the run method to return a list directly
        mock_results = [
            {
                "title": "Test Result",
                "link": "https://example.com",
                "snippet": "Snippet",
            },
        ]
        self.mock_brave.run = Mock(return_value=mock_results)

        engine = BraveSearchEngine(api_key="test_key")
        previews = engine._get_previews("test query")

        assert len(previews) == 1
        assert previews[0]["title"] == "Test Result"

    def test_get_previews_handles_invalid_json(self):
        """Test that invalid JSON responses are handled gracefully."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        # Mock the run method to return invalid JSON
        self.mock_brave.run = Mock(return_value="not valid json {{{")

        engine = BraveSearchEngine(api_key="test_key")
        previews = engine._get_previews("test query")

        assert previews == []

    def test_get_previews_handles_exception(self):
        """Test that exceptions are handled gracefully."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        # Mock the run method to raise an exception
        self.mock_brave.run = Mock(side_effect=Exception("Network error"))

        engine = BraveSearchEngine(api_key="test_key")
        previews = engine._get_previews("test query")

        assert previews == []


class TestBraveRateLimiting:
    """Tests for Brave rate limit handling."""

    @pytest.fixture(autouse=True)
    def mock_brave_search(self, monkeypatch):
        """Mock BraveSearch to avoid needing an API key."""
        self.mock_brave = Mock()
        self.mock_brave.from_api_key = Mock(return_value=self.mock_brave)
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_brave.BraveSearch",
            self.mock_brave,
        )

    def test_rate_limit_429_raises_error(self):
        """Test that 429 errors raise RateLimitError."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )
        from local_deep_research.web_search_engines.rate_limiting import (
            RateLimitError,
        )

        # Mock the run method to raise a rate limit error
        self.mock_brave.run = Mock(
            side_effect=Exception("429 Too Many Requests")
        )

        engine = BraveSearchEngine(api_key="test_key")

        with pytest.raises(RateLimitError):
            engine._get_previews("test query")

    def test_rate_limit_quota_raises_error(self):
        """Test that quota errors raise RateLimitError."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )
        from local_deep_research.web_search_engines.rate_limiting import (
            RateLimitError,
        )

        # Mock the run method to raise a quota error
        self.mock_brave.run = Mock(side_effect=Exception("Quota exceeded"))

        engine = BraveSearchEngine(api_key="test_key")

        with pytest.raises(RateLimitError):
            engine._get_previews("test query")


class TestBraveFullContent:
    """Tests for Brave full content retrieval."""

    @pytest.fixture(autouse=True)
    def mock_brave_search(self, monkeypatch):
        """Mock BraveSearch to avoid needing an API key."""
        mock_brave = Mock()
        mock_brave.from_api_key = Mock(return_value=mock_brave)
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_brave.BraveSearch",
            mock_brave,
        )

    def test_get_full_content_returns_results(self):
        """Test that full content returns processed results."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine = BraveSearchEngine(
            api_key="test_key", include_full_content=False
        )

        items = [
            {
                "title": "Test",
                "link": "https://example.com",
                "_full_result": {"title": "Full Test"},
            },
        ]

        results = engine._get_full_content(items)

        assert len(results) == 1

    def test_include_full_content_flag(self):
        """Test include_full_content flag is set correctly."""
        from local_deep_research.web_search_engines.engines.search_engine_brave import (
            BraveSearchEngine,
        )

        engine_with = BraveSearchEngine(
            api_key="test_key", include_full_content=True
        )
        assert engine_with.include_full_content is True

        engine_without = BraveSearchEngine(
            api_key="test_key", include_full_content=False
        )
        assert engine_without.include_full_content is False
