"""
Comprehensive tests for the Guardian search engine.
Tests initialization, search functionality, date handling, and query optimization.

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

import pytest
from unittest.mock import Mock


class TestGuardianSearchEngineInit:
    """Tests for Guardian search engine initialization."""

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

        engine = GuardianSearchEngine(api_key="test_api_key")

        assert engine.api_key == "test_api_key"
        assert engine.max_results >= 10
        assert engine.is_public 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_guardian import (
            GuardianSearchEngine,
        )

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

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

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

    def test_init_with_section(self):
        """Test initialization with specific section."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key", section="technology")
        assert engine.section == "technology"

    def test_init_with_order_by(self):
        """Test initialization with specific order."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key", order_by="newest")
        assert engine.order_by == "newest"

    def test_api_url_configured(self):
        """Test that API URL is properly configured."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key")
        assert engine.api_url == "https://content.guardianapis.com/search"


class TestGuardianDateConfiguration:
    """Tests for Guardian date configuration."""

    def test_default_dates_set(self):
        """Test that default dates are set automatically."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key")

        # from_date and to_date should be set
        assert engine.from_date is not None
        assert engine.to_date is not None
        # Dates should be in YYYY-MM-DD format
        assert len(engine.from_date) == 10
        assert len(engine.to_date) == 10

    def test_custom_from_date(self):
        """Test initialization with custom from date."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(
            api_key="test_key", from_date="2024-01-01"
        )
        assert engine.from_date == "2024-01-01"

    def test_custom_to_date(self):
        """Test initialization with custom to date."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key", to_date="2024-12-31")
        assert engine.to_date == "2024-12-31"

    def test_original_date_params_stored(self):
        """Test that original date parameters are stored for restoration."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(
            api_key="test_key", from_date="2024-01-01", to_date="2024-06-01"
        )
        assert engine._original_date_params["from_date"] == "2024-01-01"
        assert engine._original_date_params["to_date"] == "2024-06-01"


class TestGuardianEngineType:
    """Tests for Guardian 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_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key")
        assert "guardian" 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_guardian import (
            GuardianSearchEngine,
        )

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

    def test_engine_is_not_generic(self):
        """Test that engine is not marked as generic (it's news-specific)."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key")
        # Guardian is a news source, not a generic search engine
        assert (
            not hasattr(engine, "is_generic") or engine.is_generic is not True
        )


class TestGuardianQueryOptimization:
    """Tests for Guardian query optimization settings."""

    def test_optimize_queries_default(self):
        """Test that optimize_queries defaults to True."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key")
        assert engine.optimize_queries is True

    def test_optimize_queries_disabled(self):
        """Test that optimize_queries can be disabled."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(
            api_key="test_key", optimize_queries=False
        )
        assert engine.optimize_queries is False

    def test_adaptive_search_default(self):
        """Test that adaptive_search defaults to True."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key")
        assert engine.adaptive_search is True

    def test_adaptive_search_disabled(self):
        """Test that adaptive_search can be disabled."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key", adaptive_search=False)
        assert engine.adaptive_search is False


class TestGuardianSearchExecution:
    """Tests for Guardian search execution."""

    @pytest.fixture
    def engine(self):
        """Create a Guardian engine."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        return GuardianSearchEngine(
            api_key="test_key", optimize_queries=False, adaptive_search=False
        )

    def test_get_all_data_success(self, engine, monkeypatch):
        """Test successful data retrieval."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(
            return_value={
                "response": {
                    "results": [
                        {
                            "id": "article-1",
                            "webTitle": "Test Article 1",
                            "webUrl": "https://guardian.com/article1",
                            "webPublicationDate": "2024-01-15T10:00:00Z",
                            "sectionName": "Technology",
                            "fields": {
                                "headline": "Test Headline 1",
                                "trailText": "Test snippet 1",
                                "byline": "Test Author",
                                "body": "Full article content",
                            },
                            "tags": [],
                        },
                    ]
                }
            }
        )

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

        articles = engine._get_all_data("test query")

        assert len(articles) == 1
        assert articles[0]["id"] == "article-1"
        assert articles[0]["title"] == "Test Headline 1"

    def test_get_all_data_empty_results(self, engine, monkeypatch):
        """Test data retrieval with no results."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(return_value={"response": {"results": []}})

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

        articles = engine._get_all_data("test query")

        assert articles == []

    def test_get_all_data_handles_error(self, engine, monkeypatch):
        """Test that errors are handled gracefully."""
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_guardian.safe_get",
            Mock(side_effect=Exception("Network error")),
        )

        articles = engine._get_all_data("test query")

        assert articles == []

    def test_run_with_none_query(self, engine, monkeypatch):
        """Test that None query is handled."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.raise_for_status = Mock()
        mock_response.json = Mock(return_value={"response": {"results": []}})

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

        # Should not raise, should use default query
        results = engine.run(None)
        assert isinstance(results, list)


class TestGuardianQueryOptimizationLogic:
    """Tests for Guardian query optimization logic."""

    @pytest.fixture
    def engine(self):
        """Create a Guardian engine."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        return GuardianSearchEngine(api_key="test_key", optimize_queries=False)

    def test_optimize_query_truncates_long_queries(self, engine):
        """Test that long queries are truncated."""
        long_query = "a " * 100  # Very long query
        optimized = engine._optimize_query_for_guardian(long_query)

        # Should be truncated
        assert len(optimized) <= 150

    def test_optimize_query_returns_original_without_llm(self, engine):
        """Test that original query is returned without LLM."""
        engine.llm = None
        result = engine._optimize_query_for_guardian("test query")
        assert result == "test query"

    def test_optimize_query_returns_original_when_disabled(self, engine):
        """Test that original query is returned when optimization is disabled."""
        engine.optimize_queries = False
        result = engine._optimize_query_for_guardian("test query")
        assert result == "test query"


class TestGuardianDateAdaptation:
    """Tests for Guardian date adaptation logic."""

    @pytest.fixture
    def engine(self):
        """Create a Guardian engine."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        return GuardianSearchEngine(api_key="test_key", adaptive_search=True)

    def test_adapt_dates_short_query(self, engine):
        """Test that short queries get recent date range."""
        engine._adapt_dates_for_query_type("AI news")

        # Short queries should default to newest
        assert engine.order_by == "newest"

    def test_adapt_dates_without_llm(self, engine):
        """Test that dates are not adapted without LLM for longer queries."""
        engine.llm = None

        engine._adapt_dates_for_query_type(
            "This is a longer query that spans multiple words"
        )

        # Without LLM, dates should not change for long queries
        # (Short queries are handled differently)


class TestGuardianSpecialMethods:
    """Tests for Guardian special methods."""

    @pytest.fixture
    def engine(self):
        """Create a Guardian engine."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        return GuardianSearchEngine(api_key="test_key")

    def test_search_by_section_method_exists(self, engine):
        """Test that search_by_section method exists."""
        assert hasattr(engine, "search_by_section")
        assert callable(engine.search_by_section)

    def test_get_recent_articles_method_exists(self, engine):
        """Test that get_recent_articles method exists."""
        assert hasattr(engine, "get_recent_articles")
        assert callable(engine.get_recent_articles)


class TestGuardianOrderBySettings:
    """Tests for Guardian order_by settings."""

    def test_order_by_relevance(self):
        """Test order_by set to relevance."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key", order_by="relevance")
        assert engine.order_by == "relevance"

    def test_order_by_newest(self):
        """Test order_by set to newest."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key", order_by="newest")
        assert engine.order_by == "newest"

    def test_order_by_oldest(self):
        """Test order_by set to oldest."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key", order_by="oldest")
        assert engine.order_by == "oldest"

    def test_order_by_default(self):
        """Test default order_by value."""
        from local_deep_research.web_search_engines.engines.search_engine_guardian import (
            GuardianSearchEngine,
        )

        engine = GuardianSearchEngine(api_key="test_key")
        assert engine.order_by == "relevance"
