"""
Tests for the LLM provider auto-discovery system.

Tests cover:
- ProviderInfo class
- ProviderDiscovery singleton
- Provider discovery and registration
- Getting provider options for UI
"""

from unittest.mock import Mock


class TestProviderInfo:
    """Tests for ProviderInfo class."""

    def test_init_extracts_provider_key(self):
        """ProviderInfo extracts provider key from class."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderInfo,
        )

        mock_class = Mock()
        mock_class.__name__ = "TestProvider"
        mock_class.provider_name = "Test"
        mock_class.provider_key = "TEST"
        mock_class.company_name = "Test Company"
        mock_class.is_cloud = True
        mock_class.requires_auth_for_models = Mock(return_value=True)

        info = ProviderInfo(mock_class)

        assert info.provider_key == "TEST"
        assert info.provider_name == "Test"

    def test_init_generates_provider_key_from_class_name(self):
        """ProviderInfo generates key from class name if not specified."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderInfo,
        )

        # Create a mock class without provider_key attribute
        mock_class = Mock()
        mock_class.__name__ = "CustomProvider"
        mock_class.provider_name = "Custom"
        # Use spec to control which attributes exist
        del (
            mock_class.provider_key
        )  # Remove provider_key so it falls back to class name
        mock_class.company_name = "Custom Company"
        mock_class.is_cloud = True
        mock_class.requires_auth_for_models = Mock(return_value=True)

        info = ProviderInfo(mock_class)

        assert info.provider_name == "Custom"

    def test_to_dict_returns_expected_keys(self):
        """to_dict returns expected dictionary keys."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderInfo,
        )

        mock_class = Mock()
        mock_class.__name__ = "TestProvider"
        mock_class.provider_name = "Test Provider"
        mock_class.provider_key = "TEST"
        mock_class.company_name = "Test Company"
        mock_class.is_cloud = True
        mock_class.requires_auth_for_models = Mock(return_value=True)

        info = ProviderInfo(mock_class)
        result = info.to_dict()

        assert "value" in result
        assert "label" in result
        assert "is_cloud" in result

    def test_generate_display_name_local_provider(self):
        """Display name shows local indicator for non-cloud providers."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderInfo,
        )

        mock_class = Mock()
        mock_class.__name__ = "LocalProvider"
        mock_class.provider_name = "Local LLM"
        mock_class.provider_key = "LOCAL"
        mock_class.company_name = "Local Company"
        mock_class.is_cloud = False
        mock_class.requires_auth_for_models = Mock(return_value=False)

        info = ProviderInfo(mock_class)

        # Display name should indicate local
        assert "Local" in info.display_name


class TestProviderDiscovery:
    """Tests for ProviderDiscovery class."""

    def test_singleton_pattern(self):
        """ProviderDiscovery follows singleton pattern."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
        )

        instance1 = ProviderDiscovery()
        instance2 = ProviderDiscovery()

        assert instance1 is instance2

    def test_discover_providers_returns_dict(self):
        """discover_providers returns dictionary."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
        )

        discovery = ProviderDiscovery()
        result = discovery.discover_providers()

        assert isinstance(result, dict)

    def test_get_provider_options_returns_list(self):
        """get_provider_options returns list."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
        )

        discovery = ProviderDiscovery()
        result = discovery.get_provider_options()

        assert isinstance(result, list)

    def test_get_provider_options_sorted_by_label(self):
        """get_provider_options returns sorted list."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
        )

        discovery = ProviderDiscovery()
        options = discovery.get_provider_options()

        if len(options) > 1:
            labels = [opt["label"] for opt in options]
            assert labels == sorted(labels)

    def test_get_provider_info_returns_provider(self):
        """get_provider_info returns ProviderInfo for known provider."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
        )

        discovery = ProviderDiscovery()
        discovery.discover_providers()

        # Should have discovered some providers
        if discovery._providers:
            # Get first provider key
            first_key = list(discovery._providers.keys())[0]
            info = discovery.get_provider_info(first_key)

            assert info is not None

    def test_get_provider_info_returns_none_for_unknown(self):
        """get_provider_info returns None for unknown provider."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
        )

        discovery = ProviderDiscovery()
        result = discovery.get_provider_info("NONEXISTENT_PROVIDER_XYZ")

        assert result is None

    def test_get_provider_class_returns_class(self):
        """get_provider_class returns provider class."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
        )

        discovery = ProviderDiscovery()
        discovery.discover_providers()

        # Should have discovered some providers
        if discovery._providers:
            first_key = list(discovery._providers.keys())[0]
            cls = discovery.get_provider_class(first_key)

            assert cls is not None

    def test_get_provider_class_returns_none_for_unknown(self):
        """get_provider_class returns None for unknown provider."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
        )

        discovery = ProviderDiscovery()
        result = discovery.get_provider_class("NONEXISTENT_PROVIDER_XYZ")

        assert result is None


class TestModuleFunctions:
    """Tests for module-level functions."""

    def test_discover_providers_function(self):
        """discover_providers function works."""
        from local_deep_research.llm.providers.auto_discovery import (
            discover_providers,
        )

        result = discover_providers()

        assert isinstance(result, dict)

    def test_get_discovered_provider_options_function(self):
        """get_discovered_provider_options function works."""
        from local_deep_research.llm.providers.auto_discovery import (
            get_discovered_provider_options,
        )

        result = get_discovered_provider_options()

        assert isinstance(result, list)

    def test_get_provider_class_function(self):
        """get_provider_class function works."""
        from local_deep_research.llm.providers.auto_discovery import (
            get_provider_class,
        )

        # Test with unknown provider
        result = get_provider_class("UNKNOWN_XYZ")

        assert result is None


class TestGlobalInstance:
    """Tests for global provider_discovery instance."""

    def test_global_instance_is_provider_discovery(self):
        """Global instance is ProviderDiscovery type."""
        from local_deep_research.llm.providers.auto_discovery import (
            ProviderDiscovery,
            provider_discovery,
        )

        assert isinstance(provider_discovery, ProviderDiscovery)
