"""
Comprehensive tests for the ScaleSERP search engine (Google via ScaleSERP API).
Tests initialization, search functionality, caching, and result formatting.

Note: These tests mock HTTP requests to avoid requiring an API key.
"""

import pytest
from unittest.mock import Mock


class TestScaleSerpSearchEngineInit:
    """Tests for ScaleSERP search engine initialization."""

    def test_init_default_values(self):
        """Test initialization with default values."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        engine = ScaleSerpSearchEngine(api_key="test_key")

        assert engine.max_results == 10
        assert engine.location == "United States"
        assert engine.language == "en"
        assert engine.device == "desktop"
        assert engine.safe_search is True
        assert engine.enable_cache is True
        assert engine.is_public is True
        assert engine.is_generic is True

    def test_init_with_custom_max_results(self):
        """Test initialization with custom max results."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        engine = ScaleSerpSearchEngine(api_key="test_key", max_results=50)
        assert engine.max_results == 50

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

        engine = ScaleSerpSearchEngine(api_key="my_api_key")
        assert engine.api_key == "my_api_key"

    def test_init_without_api_key_raises_error(self, monkeypatch):
        """Test that initialization without API key raises ValueError."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        monkeypatch.setattr(
            "local_deep_research.config.search_config.get_setting_from_snapshot",
            Mock(return_value=None),
        )

        with pytest.raises(
            ValueError, match="No valid API key found for ScaleSerp"
        ):
            ScaleSerpSearchEngine()

    def test_init_with_location(self):
        """Test initialization with custom location."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        engine = ScaleSerpSearchEngine(
            api_key="test_key", location="London,England,United Kingdom"
        )
        assert engine.location == "London,England,United Kingdom"

    def test_init_with_device(self):
        """Test initialization with different device type."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        engine = ScaleSerpSearchEngine(api_key="test_key", device="mobile")
        assert engine.device == "mobile"

    def test_init_with_cache_disabled(self):
        """Test initialization with caching disabled."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        engine = ScaleSerpSearchEngine(api_key="test_key", enable_cache=False)
        assert engine.enable_cache is False

    def test_init_with_safe_search_disabled(self):
        """Test initialization with safe search disabled."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        engine = ScaleSerpSearchEngine(api_key="test_key", safe_search=False)
        assert engine.safe_search is False

    def test_base_url_set(self):
        """Test that base URL is correctly set."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        engine = ScaleSerpSearchEngine(api_key="test_key")
        assert engine.base_url == "https://api.scaleserp.com/search"


class TestScaleSerpEngineType:
    """Tests for ScaleSERP engine type identification."""

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

        engine = ScaleSerpSearchEngine(api_key="test_key")
        assert "scaleserp" 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_scaleserp import (
            ScaleSerpSearchEngine,
        )

        engine = ScaleSerpSearchEngine(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_scaleserp import (
            ScaleSerpSearchEngine,
        )

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


class TestScaleSerpSearchExecution:
    """Tests for ScaleSERP search execution."""

    @pytest.fixture
    def engine(self):
        """Create a ScaleSERP engine."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        return ScaleSerpSearchEngine(api_key="test_key", max_results=10)

    def test_get_previews_success(self, engine, monkeypatch):
        """Test successful preview retrieval."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(
            return_value={
                "organic_results": [
                    {
                        "position": 1,
                        "title": "Test Result",
                        "link": "https://example.com/page",
                        "snippet": "This is a test snippet.",
                    },
                    {
                        "position": 2,
                        "title": "Second Result",
                        "link": "https://test.org/article",
                        "snippet": "Another snippet.",
                    },
                ],
                "request_info": {"cached": False},
            }
        )

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(return_value=mock_response),
        )

        previews = engine._get_previews("test query")

        assert len(previews) == 2
        assert previews[0]["title"] == "Test Result"
        assert previews[0]["link"] == "https://example.com/page"
        assert previews[0]["from_cache"] is False

    def test_get_previews_from_cache(self, engine, monkeypatch):
        """Test preview retrieval from cache."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(
            return_value={
                "organic_results": [
                    {
                        "position": 1,
                        "title": "Cached Result",
                        "link": "https://example.com",
                        "snippet": "Test",
                    }
                ],
                "request_info": {"cached": True},
            }
        )

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(return_value=mock_response),
        )

        previews = engine._get_previews("test query")

        assert len(previews) == 1
        assert previews[0]["from_cache"] is True

    def test_get_previews_with_knowledge_graph(self, engine, monkeypatch):
        """Test preview retrieval with knowledge graph."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(
            return_value={
                "organic_results": [
                    {
                        "title": "Test",
                        "link": "https://example.com",
                        "snippet": "Test",
                    }
                ],
                "request_info": {"cached": False},
                "knowledge_graph": {
                    "title": "Test Entity",
                    "type": "Organization",
                },
            }
        )

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(return_value=mock_response),
        )

        engine._get_previews("test query")

        assert hasattr(engine, "_knowledge_graph")
        assert engine._knowledge_graph["title"] == "Test Entity"

    def test_get_previews_empty_results(self, engine, monkeypatch):
        """Test preview retrieval with no results."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(
            return_value={
                "organic_results": [],
                "request_info": {"cached": False},
            }
        )

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(return_value=mock_response),
        )

        previews = engine._get_previews("nonexistent topic xyz123")

        assert previews == []

    def test_get_previews_rate_limit_error(self, engine, monkeypatch):
        """Test that 429 errors raise RateLimitError."""
        from local_deep_research.web_search_engines.rate_limiting import (
            RateLimitError,
        )

        mock_response = Mock()
        mock_response.status_code = 429
        mock_response.text = "Rate limit exceeded"

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(return_value=mock_response),
        )

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

    def test_get_previews_handles_request_exception(self, engine, monkeypatch):
        """Test that request exceptions are handled gracefully."""
        import requests

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(
                side_effect=requests.exceptions.RequestException(
                    "Network error"
                )
            ),
        )

        previews = engine._get_previews("test query")
        assert previews == []


class TestScaleSerpRichSnippets:
    """Tests for ScaleSERP rich snippet handling."""

    @pytest.fixture
    def engine(self):
        """Create a ScaleSERP engine."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        return ScaleSerpSearchEngine(api_key="test_key")

    def test_rich_snippets_included(self, engine, monkeypatch):
        """Test that rich snippets are included in results."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(
            return_value={
                "organic_results": [
                    {
                        "title": "Test",
                        "link": "https://example.com",
                        "snippet": "Test",
                        "rich_snippet": {
                            "rating": "4.5",
                            "reviews": "1000",
                        },
                    }
                ],
                "request_info": {"cached": False},
            }
        )

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(return_value=mock_response),
        )

        previews = engine._get_previews("test")

        assert "rich_snippet" in previews[0]
        assert previews[0]["rich_snippet"]["rating"] == "4.5"

    def test_sitelinks_included(self, engine, monkeypatch):
        """Test that sitelinks are included in results."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(
            return_value={
                "organic_results": [
                    {
                        "title": "Test",
                        "link": "https://example.com",
                        "snippet": "Test",
                        "sitelinks": [
                            {
                                "title": "About",
                                "link": "https://example.com/about",
                            }
                        ],
                    }
                ],
                "request_info": {"cached": False},
            }
        )

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(return_value=mock_response),
        )

        previews = engine._get_previews("test")

        assert "sitelinks" in previews[0]


class TestScaleSerpFullContent:
    """Tests for ScaleSERP full content retrieval."""

    @pytest.fixture
    def engine(self):
        """Create a ScaleSERP engine."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        return ScaleSerpSearchEngine(api_key="test_key")

    def test_get_full_content_with_full_result(self, engine, monkeypatch):
        """Test full content retrieval with _full_result available."""
        import local_deep_research.config.search_config as search_config_module

        if hasattr(search_config_module, "SEARCH_SNIPPETS_ONLY"):
            monkeypatch.delattr(
                "local_deep_research.config.search_config.SEARCH_SNIPPETS_ONLY",
                raising=False,
            )

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

        results = engine._get_full_content(items)

        assert len(results) == 1
        assert results[0]["title"] == "Test Result"
        assert "_full_result" not in results[0]


class TestScaleSerpURLParsing:
    """Tests for ScaleSERP URL parsing in results."""

    @pytest.fixture
    def engine(self):
        """Create a ScaleSERP engine."""
        from local_deep_research.web_search_engines.engines.search_engine_scaleserp import (
            ScaleSerpSearchEngine,
        )

        return ScaleSerpSearchEngine(api_key="test_key")

    def test_display_link_extraction(self, engine, monkeypatch):
        """Test that display link is extracted from URL."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(
            return_value={
                "organic_results": [
                    {
                        "title": "Test",
                        "link": "https://www.example.com/path/to/page",
                        "snippet": "Test",
                    }
                ],
                "request_info": {"cached": False},
            }
        )

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_scaleserp.safe_get",
            Mock(return_value=mock_response),
        )

        previews = engine._get_previews("test")

        assert previews[0]["displayed_link"] == "www.example.com"
