"""
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"


class TestSearXNGValidSearchResult:
    """Tests for _is_valid_search_result method."""

    @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_valid_https_url(self):
        """Test valid HTTPS URL is accepted."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert engine._is_valid_search_result("https://example.com") is True

    def test_valid_http_url(self):
        """Test valid HTTP URL is accepted."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert engine._is_valid_search_result("http://example.com") is True

    def test_relative_url_rejected(self):
        """Test relative URL is rejected."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert engine._is_valid_search_result("/stats?engine=google") is False

    def test_empty_url_rejected(self):
        """Test empty URL is rejected."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert engine._is_valid_search_result("") is False
        assert engine._is_valid_search_result(None) is False

    def test_instance_url_rejected(self):
        """Test URLs pointing to instance itself are rejected."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(instance_url="http://localhost:8080")
        assert (
            engine._is_valid_search_result(
                "http://localhost:8080/stats?engine=google"
            )
            is False
        )
        assert (
            engine._is_valid_search_result("http://localhost:8080/preferences")
            is False
        )

    def test_case_insensitive_scheme(self):
        """Test URL scheme check is case insensitive."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        assert engine._is_valid_search_result("HTTPS://example.com") is True
        assert engine._is_valid_search_result("HTTP://example.com") is True


class TestSearXNGSearchResults:
    """Tests for SearXNG search result parsing."""

    @pytest.fixture
    def mock_html_response(self):
        """Mock HTML response with search results."""
        return """
        <html>
        <body>
            <div class="result-item">
                <h3 class="result-title"><a href="https://example.com/1">Result 1</a></h3>
                <p class="result-content">This is the first result snippet.</p>
            </div>
            <div class="result-item">
                <h3 class="result-title"><a href="https://example.com/2">Result 2</a></h3>
                <p class="result-content">This is the second result snippet.</p>
            </div>
        </body>
        </html>
        """

    def test_get_search_results_parses_html(
        self, monkeypatch, mock_html_response
    ):
        """Test HTML parsing of search results."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        mock_response.text = mock_html_response

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

        engine = SearXNGSearchEngine()
        results = engine._get_search_results("test query")

        assert len(results) == 2
        assert results[0]["url"] == "https://example.com/1"
        assert results[0]["title"] == "Result 1"

    def test_get_search_results_unavailable(self, monkeypatch):
        """Test _get_search_results returns empty when unavailable."""
        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()
        engine.is_available = False

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

    def test_get_search_results_filters_invalid(self, monkeypatch):
        """Test that invalid search results are filtered out."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        # HTML with one valid result and one invalid (pointing to instance)
        html = """
        <html>
        <body>
            <div class="result-item">
                <h3 class="result-title"><a href="https://example.com">Valid</a></h3>
                <p class="result-content">Valid result.</p>
            </div>
            <div class="result-item">
                <h3 class="result-title"><a href="http://localhost:8080/stats?engine=google">Engine Error</a></h3>
                <p class="result-content">Engine failed.</p>
            </div>
        </body>
        </html>
        """
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.cookies = {}
        mock_response.text = html

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

        engine = SearXNGSearchEngine()
        results = engine._get_search_results("test")

        # Should only have 1 valid result
        assert len(results) == 1
        assert results[0]["url"] == "https://example.com"

    def test_get_search_results_error_response(self, monkeypatch):
        """Test handling of error response from SearXNG."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        mock_init_response = Mock()
        mock_init_response.status_code = 200
        mock_init_response.cookies = {}

        mock_search_response = Mock()
        mock_search_response.status_code = 500

        call_count = [0]

        def mock_get(*args, **kwargs):
            call_count[0] += 1
            if call_count[0] <= 2:  # Init calls
                return mock_init_response
            return mock_search_response

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            mock_get,
        )

        engine = SearXNGSearchEngine()
        results = engine._get_search_results("test")

        assert results == []

    def test_get_search_results_exception(self, monkeypatch):
        """Test handling of exception during search."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        mock_init_response = Mock()
        mock_init_response.status_code = 200
        mock_init_response.cookies = {}

        call_count = [0]

        def mock_get(*args, **kwargs):
            call_count[0] += 1
            if call_count[0] <= 2:
                return mock_init_response
            raise Exception("Network error")

        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.safe_get",
            mock_get,
        )

        engine = SearXNGSearchEngine()
        results = engine._get_search_results("test")

        assert results == []


class TestSearXNGGetPreviews:
    """Tests for _get_previews method."""

    @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_formats_results(self, monkeypatch):
        """Test that previews are formatted correctly."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()

        # Mock _get_search_results
        mock_results = [
            {
                "title": "Title 1",
                "url": "https://example.com/1",
                "content": "Snippet 1",
            },
            {
                "title": "Title 2",
                "url": "https://example.com/2",
                "content": "Snippet 2",
            },
        ]
        engine._get_search_results = Mock(return_value=mock_results)

        previews = engine._get_previews("test")

        assert len(previews) == 2
        assert previews[0]["title"] == "Title 1"
        assert previews[0]["link"] == "https://example.com/1"
        assert previews[0]["snippet"] == "Snippet 1"
        assert previews[0]["id"] == "https://example.com/1"

    def test_get_previews_handles_empty_results(self, monkeypatch):
        """Test that empty results are handled."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        engine._get_search_results = Mock(return_value=[])

        previews = engine._get_previews("test")

        assert previews == []

    def test_get_previews_generates_id_when_no_url(self, monkeypatch):
        """Test that ID is generated when URL is missing."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        engine._get_search_results = Mock(
            return_value=[{"title": "Title", "url": "", "content": "Snippet"}]
        )

        previews = engine._get_previews("test")

        assert previews[0]["id"] == "searxng-result-0"


class TestSearXNGGetFullContent:
    """Tests for _get_full_content method."""

    @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_get_full_content_unavailable(self):
        """Test _get_full_content returns items when unavailable."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        engine.is_available = False

        items = [{"title": "Test", "snippet": "Content"}]
        results = engine._get_full_content(items)

        assert results == items

    def test_get_full_content_exception(self, monkeypatch):
        """Test _get_full_content handles exceptions."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()

        # Mock full_search to raise exception
        engine.full_search = Mock()
        engine.full_search._get_full_content = Mock(
            side_effect=Exception("Error")
        )

        items = [{"title": "Test", "snippet": "Content"}]
        results = engine._get_full_content(items)

        # Should return original items on error
        assert results == items


class TestSearXNGResultsMethod:
    """Tests for results method."""

    @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_results_formats_output(self):
        """Test results method formats output correctly."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        engine._get_search_results = Mock(
            return_value=[
                {
                    "title": "Title",
                    "url": "https://example.com",
                    "content": "Snippet",
                }
            ]
        )

        results = engine.results("test")

        assert len(results) == 1
        assert results[0]["title"] == "Title"
        assert results[0]["link"] == "https://example.com"
        assert results[0]["snippet"] == "Snippet"

    def test_results_respects_max_results_override(self):
        """Test results method respects max_results override."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(max_results=10)
        original_max = engine.max_results

        engine._get_search_results = Mock(return_value=[])
        engine.results("test", max_results=50)

        # Should restore original max_results after call
        assert engine.max_results == original_max

    def test_results_restores_max_results_on_exception(self):
        """Test max_results is restored even on exception."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine(max_results=10)
        original_max = engine.max_results

        engine._get_search_results = Mock(side_effect=Exception("Error"))

        try:
            engine.results("test", max_results=50)
        except Exception:
            pass

        # Should restore original max_results even on error
        assert engine.max_results == original_max


class TestSearXNGRateLimitMethod:
    """Tests for _respect_rate_limit method."""

    @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_respect_rate_limit_updates_time(self, monkeypatch):
        """Test that _respect_rate_limit updates last_request_time."""

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

        engine = SearXNGSearchEngine(delay_between_requests=0)
        engine.last_request_time = 0

        engine._respect_rate_limit()

        assert engine.last_request_time > 0

    def test_respect_rate_limit_waits_when_needed(self, monkeypatch):
        """Test that _respect_rate_limit waits when delay is needed."""
        import time

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

        sleep_called = []
        monkeypatch.setattr(
            "local_deep_research.web_search_engines.engines.search_engine_searxng.time.sleep",
            lambda x: sleep_called.append(x),
        )

        engine = SearXNGSearchEngine(delay_between_requests=1.0)
        engine.last_request_time = time.time()

        engine._respect_rate_limit()

        # Should have called sleep
        assert len(sleep_called) > 0


class TestSearXNGInvokeMethod:
    """Tests for invoke method (LangChain compatibility)."""

    @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_invoke_calls_run(self):
        """Test invoke method calls run."""
        from local_deep_research.web_search_engines.engines.search_engine_searxng import (
            SearXNGSearchEngine,
        )

        engine = SearXNGSearchEngine()
        engine.run = Mock(return_value=[{"title": "Test"}])

        result = engine.invoke("test query")

        engine.run.assert_called_once_with("test query")
        assert result == [{"title": "Test"}]
