"""
Tests for the retriever registry.

Tests cover:
- Registering retrievers
- Getting retrievers
- Unregistering retrievers
- Listing retrievers
- Thread safety
"""

from unittest.mock import Mock


class TestRetrieverRegistryInit:
    """Tests for RetrieverRegistry initialization."""

    def test_init_creates_empty_registry(self):
        """Initialization creates empty registry."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        assert registry.list_registered() == []

    def test_init_creates_lock(self):
        """Initialization creates lock for thread safety."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        assert registry._lock is not None


class TestRegister:
    """Tests for register method."""

    def test_register_single_retriever(self):
        """Register a single retriever."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        mock_retriever = Mock()

        registry.register("test_retriever", mock_retriever)

        assert registry.is_registered("test_retriever")
        assert registry.get("test_retriever") is mock_retriever

    def test_register_overwrites_existing(self):
        """Registering with same name overwrites existing."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        mock_retriever1 = Mock()
        mock_retriever2 = Mock()

        registry.register("test", mock_retriever1)
        registry.register("test", mock_retriever2)

        assert registry.get("test") is mock_retriever2


class TestRegisterMultiple:
    """Tests for register_multiple method."""

    def test_register_multiple_retrievers(self):
        """Register multiple retrievers at once."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        mock_retriever1 = Mock()
        mock_retriever2 = Mock()

        registry.register_multiple(
            {"retriever1": mock_retriever1, "retriever2": mock_retriever2}
        )

        assert registry.is_registered("retriever1")
        assert registry.is_registered("retriever2")

    def test_register_multiple_empty_dict(self):
        """Registering empty dict does nothing."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        registry.register_multiple({})

        assert registry.list_registered() == []


class TestGet:
    """Tests for get method."""

    def test_get_existing_retriever(self):
        """Get existing retriever."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        mock_retriever = Mock()
        registry.register("test", mock_retriever)

        result = registry.get("test")

        assert result is mock_retriever

    def test_get_nonexistent_retriever(self):
        """Get non-existent retriever returns None."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        result = registry.get("nonexistent")

        assert result is None


class TestUnregister:
    """Tests for unregister method."""

    def test_unregister_existing(self):
        """Unregister existing retriever."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        mock_retriever = Mock()
        registry.register("test", mock_retriever)

        registry.unregister("test")

        assert not registry.is_registered("test")

    def test_unregister_nonexistent(self):
        """Unregister non-existent retriever does nothing."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        # Should not raise
        registry.unregister("nonexistent")

        assert registry.list_registered() == []


class TestClear:
    """Tests for clear method."""

    def test_clear_removes_all(self):
        """Clear removes all registered retrievers."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        registry.register("test1", Mock())
        registry.register("test2", Mock())

        registry.clear()

        assert registry.list_registered() == []

    def test_clear_empty_registry(self):
        """Clear on empty registry does nothing."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        registry.clear()

        assert registry.list_registered() == []


class TestIsRegistered:
    """Tests for is_registered method."""

    def test_is_registered_true(self):
        """is_registered returns True for registered retriever."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        registry.register("test", Mock())

        assert registry.is_registered("test") is True

    def test_is_registered_false(self):
        """is_registered returns False for non-registered retriever."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        assert registry.is_registered("test") is False


class TestListRegistered:
    """Tests for list_registered method."""

    def test_list_empty_registry(self):
        """list_registered returns empty list for empty registry."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        assert registry.list_registered() == []

    def test_list_all_registered(self):
        """list_registered returns all registered names."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        registry.register("test1", Mock())
        registry.register("test2", Mock())

        result = registry.list_registered()

        assert sorted(result) == ["test1", "test2"]


class TestGlobalRegistry:
    """Tests for global registry instance."""

    def test_global_registry_exists(self):
        """Global registry instance exists."""
        from local_deep_research.web_search_engines.retriever_registry import (
            retriever_registry,
        )

        assert retriever_registry is not None

    def test_global_registry_is_retriever_registry(self):
        """Global registry is RetrieverRegistry instance."""
        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
            retriever_registry,
        )

        assert isinstance(retriever_registry, RetrieverRegistry)


class TestThreadSafety:
    """Tests for thread safety."""

    def test_concurrent_registration(self):
        """Concurrent registration is thread-safe."""
        from concurrent.futures import ThreadPoolExecutor

        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()

        def register_retriever(name):
            registry.register(name, Mock())
            return name

        with ThreadPoolExecutor(max_workers=10) as executor:
            futures = [
                executor.submit(register_retriever, f"retriever_{i}")
                for i in range(100)
            ]
            [f.result() for f in futures]

        assert len(registry.list_registered()) == 100

    def test_concurrent_get_and_register(self):
        """Concurrent get and register operations are thread-safe."""
        from concurrent.futures import ThreadPoolExecutor

        from local_deep_research.web_search_engines.retriever_registry import (
            RetrieverRegistry,
        )

        registry = RetrieverRegistry()
        mock_retriever = Mock()
        registry.register("shared", mock_retriever)

        def get_or_register(i):
            if i % 2 == 0:
                return registry.get("shared")
            registry.register(f"new_{i}", Mock())
            return None

        with ThreadPoolExecutor(max_workers=10) as executor:
            futures = [executor.submit(get_or_register, i) for i in range(100)]
            [f.result() for f in futures]

        # Should have the original plus 50 new ones
        assert registry.is_registered("shared")
        assert len(registry.list_registered()) >= 1
