"""End-to-end tests for retriever integration."""

import pytest
from langchain_core.retrievers import BaseRetriever, Document

from local_deep_research.api import detailed_research, quick_summary
from local_deep_research.web_search_engines.retriever_registry import (
    retriever_registry,
)
from local_deep_research.web_search_engines.search_engine_factory import (
    create_search_engine,
)

# Minimal non-empty snapshot so the factory's egress PEP can run; under the
# default ``both`` scope a local retriever is permitted. The factory now
# fails closed (no_snapshot) without one.
_BOTH_SNAPSHOT = {"policy.egress_scope": {"value": "both"}}


class SimpleRetriever(BaseRetriever):
    """Simple retriever that returns fixed content."""

    def _get_relevant_documents(self, query: str):
        return [
            Document(
                page_content=f"This is a comprehensive answer about {query}. It contains detailed information that should help answer the question.",
                metadata={
                    "title": f"Document about {query}",
                    "source": "test_knowledge_base",
                    "author": "Test System",
                    "score": 0.95,
                },
            ),
            Document(
                page_content=f"Additional context about {query}. This provides supporting information and examples.",
                metadata={
                    "title": f"Supporting info for {query}",
                    "source": "test_knowledge_base",
                    "score": 0.85,
                },
            ),
        ]

    async def _aget_relevant_documents(self, query: str):
        return self._get_relevant_documents(query)


@pytest.mark.skipif(
    condition=True,  # Skip in CI by default as it requires full LLM
    reason="E2E test requires working LLM - set E2E_TESTS=true to run",
)
class TestE2EBasic:
    """Basic end-to-end tests that use real components."""

    def test_simple_retriever_e2e(self):
        """Test using a retriever with quick_summary end-to-end."""
        import os

        if not os.environ.get("E2E_TESTS"):
            pytest.skip("Set E2E_TESTS=true to run end-to-end tests")

        # Create retriever
        retriever = SimpleRetriever()

        # Use with quick_summary
        result = quick_summary(
            query="What is machine learning?",
            retrievers={"test_kb": retriever},
            search_tool="test_kb",
            iterations=1,
            questions_per_iteration=1,
        )

        # Verify basic structure
        assert "summary" in result
        assert len(result["summary"]) > 0
        assert "findings" in result
        assert "sources" in result

    def test_retriever_through_factory_e2e(self):
        """Test creating retriever search engine through factory."""
        import os

        if not os.environ.get("E2E_TESTS"):
            pytest.skip("Set E2E_TESTS=true to run end-to-end tests")

        # Register retriever
        retriever = SimpleRetriever()
        retriever_registry.register("e2e_test", retriever)

        # Create search engine through factory
        engine = create_search_engine(
            "e2e_test", settings_snapshot=_BOTH_SNAPSHOT
        )

        assert engine is not None
        assert engine.name == "e2e_test"

        # Test search
        results = engine.run("test query")
        assert len(results) == 2
        assert "Document about test query" in results[0]["title"]

    def test_multiple_retrievers_e2e(self):
        """Test using multiple retrievers."""
        import os

        if not os.environ.get("E2E_TESTS"):
            pytest.skip("Set E2E_TESTS=true to run end-to-end tests")

        # Create multiple retrievers with different content
        tech_retriever = SimpleRetriever()
        business_retriever = SimpleRetriever()

        result = detailed_research(
            query="What are the implications of AI?",
            retrievers={"tech": tech_retriever, "business": business_retriever},
            search_tool="tech",
            iterations=1,
        )

        assert result["query"] == "What are the implications of AI?"
        assert "research_id" in result
        assert "metadata" in result


class TestBasicIntegration:
    """Basic integration tests that don't require LLM."""

    def test_retriever_registration_and_search(self):
        """Test that retrievers can be registered and used for search."""
        # Create and register retriever
        retriever = SimpleRetriever()
        retriever_registry.register("integration_test", retriever)

        # Create search engine
        engine = create_search_engine(
            "integration_test", settings_snapshot=_BOTH_SNAPSHOT
        )

        # Perform search
        results = engine.run("integration test query")

        # Verify results
        assert len(results) == 2
        assert results[0]["source"] == "integration_test"
        assert results[0]["retriever_type"] == "SimpleRetriever"
        assert "integration test query" in results[0]["title"]
        assert results[0]["score"] == 0.95

    def test_retriever_appears_in_config(self):
        """Test that registered retrievers appear in search config."""
        from local_deep_research.web_search_engines.search_engines_config import (
            search_config,
        )

        # Register retriever
        retriever = SimpleRetriever()
        retriever_registry.register("config_test", retriever)

        # Get config
        config = search_config()

        # Verify retriever is in config
        assert "config_test" in config
        assert config["config_test"]["is_retriever"]
        assert config["config_test"]["class_name"] == "RetrieverSearchEngine"

    def test_retriever_cleanup_between_tests(self):
        """Test that registry is cleaned between tests."""
        # Should start empty due to cleanup fixture
        assert len(retriever_registry.list_registered()) == 0

        # Register some retrievers
        for i in range(3):
            retriever_registry.register(f"cleanup_test_{i}", SimpleRetriever())

        assert len(retriever_registry.list_registered()) == 3
        # Cleanup fixture will clear these after test
