"""
Comprehensive tests for the SearXNG search engine.
Tests initialization, configuration, and search functionality.

Note: These tests mock HTTP requests to avoid requiring a running SearXNG instance.
"""

import pytest
from unittest.mock import Mock


class TestSearXNGSearchEngineInit:
    """Tests for SearXNG search engine initialization."""

    @pytest.fixture(autouse=True)
    def mock_safe_get(self, monkeypatch):
        """Mock safe_get to avoid HTTP requests."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(return_value=mock_response),
        )

    def test_init_default_parameters(self):
        """Test initialization with default parameters."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()

        assert engine.max_results >= 10
        assert engine.is_public is True
        assert engine.is_generic is True
        assert engine.instance_url == "http://localhost:8080"

    def test_init_custom_instance_url(self):
        """Test initialization with custom instance URL."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(instance_url="http://mysearxng.local:9000")
        assert engine.instance_url == "http://mysearxng.local:9000"

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

        engine = SearXNGSearchEngine(max_results=50)
        assert engine.max_results >= 50

    def test_init_with_categories(self):
        """Test initialization with specific categories."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(categories=["images", "videos"])
        assert engine.categories == ["images", "videos"]

    def test_init_with_engines(self):
        """Test initialization with specific search engines."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(engines=["google", "bing"])
        assert engine.engines == ["google", "bing"]

    def test_init_with_language(self):
        """Test initialization with specific language."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(language="de")
        assert engine.language == "de"


class TestSearXNGSafeSearchSettings:
    """Tests for SearXNG safe search configuration."""

    @pytest.fixture(autouse=True)
    def mock_safe_get(self, monkeypatch):
        """Mock safe_get to avoid HTTP requests."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(return_value=mock_response),
        )

    def test_safe_search_off(self):
        """Test safe search OFF setting."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SafeSearchSetting,
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(safe_search="OFF")
        assert engine.safe_search == SafeSearchSetting.OFF

    def test_safe_search_moderate(self):
        """Test safe search MODERATE setting."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SafeSearchSetting,
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(safe_search="MODERATE")
        assert engine.safe_search == SafeSearchSetting.MODERATE

    def test_safe_search_strict(self):
        """Test safe search STRICT setting."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SafeSearchSetting,
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(safe_search="STRICT")
        assert engine.safe_search == SafeSearchSetting.STRICT

    def test_safe_search_integer_value(self):
        """Test safe search with integer values."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SafeSearchSetting,
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(safe_search=1)
        assert engine.safe_search == SafeSearchSetting.MODERATE

    def test_safe_search_invalid_defaults_to_off(self):
        """Test that invalid safe search value defaults to OFF."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SafeSearchSetting,
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(safe_search="INVALID")
        assert engine.safe_search == SafeSearchSetting.OFF


class TestSearXNGAvailability:
    """Tests for SearXNG instance availability checking."""

    def test_instance_available_when_200(self, monkeypatch):
        """Test that engine is marked available on 200 response."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(return_value=mock_response),
        )

        engine = SearXNGSearchEngine()
        assert engine.is_available is True

    def test_instance_unavailable_when_error(self, monkeypatch):
        """Test that engine is marked unavailable on error response."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        mock_response = Mock()
        mock_response.status_code = 500
        mock_response.cookies = {}
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(return_value=mock_response),
        )

        engine = SearXNGSearchEngine()
        assert engine.is_available is False

    def test_instance_unavailable_when_connection_error(self, monkeypatch):
        """Test that engine is marked unavailable on connection error."""
        import requests

        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(side_effect=requests.RequestException("Connection refused")),
        )

        engine = SearXNGSearchEngine()
        assert engine.is_available is False


class TestSearXNGEngineType:
    """Tests for SearXNG engine type identification."""

    @pytest.fixture(autouse=True)
    def mock_safe_get(self, monkeypatch):
        """Mock safe_get to avoid HTTP requests."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(return_value=mock_response),
        )

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

        engine = SearXNGSearchEngine()
        assert "searxng" 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_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        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_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert engine.is_generic is True


class TestSearXNGSearchExecution:
    """Tests for SearXNG search execution."""

    @pytest.fixture(autouse=True)
    def mock_safe_get(self, monkeypatch):
        """Mock safe_get to avoid HTTP requests."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        mock_response.text = ""
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(return_value=mock_response),
        )

    def test_get_previews_when_unavailable(self):
        """Test that _get_previews returns empty when unavailable."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        engine.is_available = False

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

    def test_run_when_unavailable(self):
        """Test that run returns empty when unavailable."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        engine.is_available = False

        results = engine.run("test query")
        assert results == []

    def test_results_method_when_unavailable(self):
        """Test that results method returns empty when unavailable."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        engine.is_available = False

        results = engine.results("test query")
        assert results == []


class TestSearXNGRateLimiting:
    """Tests for SearXNG rate limiting."""

    @pytest.fixture(autouse=True)
    def mock_safe_get(self, monkeypatch):
        """Mock safe_get to avoid HTTP requests."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(return_value=mock_response),
        )

    def test_delay_between_requests_default(self):
        """Test default delay between requests."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert engine.delay_between_requests == 0.0

    def test_delay_between_requests_custom(self):
        """Test custom delay between requests."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(delay_between_requests=2.5)
        assert engine.delay_between_requests == 2.5

    def test_last_request_time_initialized(self):
        """Test that last_request_time is initialized."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert hasattr(engine, "last_request_time")
        assert engine.last_request_time == 0


class TestSearXNGStaticMethods:
    """Tests for SearXNG static methods."""

    def test_get_self_hosting_instructions(self):
        """Test that self-hosting instructions are provided."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        instructions = SearXNGSearchEngine.get_self_hosting_instructions()

        assert "docker" in instructions.lower()
        assert "searxng" in instructions.lower()
        assert "8080" in instructions


class TestSearXNGTimeRange:
    """Tests for SearXNG time range configuration."""

    @pytest.fixture(autouse=True)
    def mock_safe_get(self, monkeypatch):
        """Mock safe_get to avoid HTTP requests."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            Mock(return_value=mock_response),
        )

    def test_time_range_default(self):
        """Test default time range is None."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert engine.time_range is None

    def test_time_range_day(self):
        """Test time range set to day."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(time_range="day")
        assert engine.time_range == "day"

    def test_time_range_week(self):
        """Test time range set to week."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(time_range="week")
        assert engine.time_range == "week"

    def test_time_range_month(self):
        """Test time range set to month."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(time_range="month")
        assert engine.time_range == "month"

    def test_time_range_year(self):
        """Test time range set to year."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(time_range="year")
        assert engine.time_range == "year"
