"""
Tests for LLM config Ollama provider specifics.

Tests cover:
- Ollama provider edge cases
- Ollama availability checks
"""


class TestOllamaProviderEdgeCases:
    """Tests for Ollama provider edge cases."""

    def test_ollama_model_not_found_error(self):
        """Ollama model not found returns fallback."""
        model_name = "nonexistent-model"
        available_models = ["mistral", "llama2", "codellama"]

        model_found = model_name.lower() in [
            m.lower() for m in available_models
        ]

        assert not model_found

    def test_ollama_service_unavailable_503(self):
        """Ollama 503 triggers fallback."""
        status_code = 503

        if status_code == 503:
            use_fallback = True
        else:
            use_fallback = False

        assert use_fallback

    def test_ollama_connection_refused(self):
        """Connection refused triggers fallback."""
        error_message = "Connection refused: localhost:11434"

        if "connection refused" in error_message.lower():
            use_fallback = True
        else:
            use_fallback = False

        assert use_fallback

    def test_ollama_timeout_handling(self):
        """Timeout triggers fallback."""
        error_message = "Request timeout"

        if "timeout" in error_message.lower():
            use_fallback = True
        else:
            use_fallback = False

        assert use_fallback

    def test_ollama_thinking_mode_enabled(self):
        """Thinking mode enables reasoning parameter."""
        enable_thinking = True

        if enable_thinking:
            ollama_params = {"reasoning": True}
        else:
            ollama_params = {}

        assert ollama_params.get("reasoning") is True

    def test_ollama_thinking_mode_disabled(self):
        """Thinking mode disabled omits reasoning parameter."""
        enable_thinking = False

        if enable_thinking:
            ollama_params = {"reasoning": True}
        else:
            ollama_params = {}

        assert (
            "reasoning" not in ollama_params
            or ollama_params.get("reasoning") is False
        )

    def test_ollama_base_url_normalization_trailing_slash(self):
        """Base URL trailing slash is normalized."""
        raw_url = "http://localhost:11434/"

        # Normalize by removing trailing slash
        normalized_url = raw_url.rstrip("/")

        assert normalized_url == "http://localhost:11434"

    def test_ollama_base_url_normalization_no_slash(self):
        """Base URL without trailing slash is kept."""
        raw_url = "http://localhost:11434"

        normalized_url = raw_url.rstrip("/")

        assert normalized_url == "http://localhost:11434"

    def test_ollama_api_format_default(self):
        """Default API format is Ollama native."""
        api_format = "ollama"

        assert api_format == "ollama"

    def test_ollama_api_format_openai_compatible(self):
        """OpenAI compatible format is supported."""
        api_format = "openai_compatible"

        # Some Ollama setups use OpenAI format
        assert api_format in ["ollama", "openai_compatible"]

    def test_ollama_model_list_empty(self):
        """Empty model list triggers fallback."""
        models = []

        if not models:
            use_fallback = True
        else:
            use_fallback = False

        assert use_fallback

    def test_ollama_model_list_parsing(self):
        """Model list is parsed correctly."""
        response_data = {
            "models": [
                {"name": "mistral:latest", "size": 4000000000},
                {"name": "llama2:7b", "size": 3500000000},
            ]
        }

        models = [
            m.get("name", "").lower() for m in response_data.get("models", [])
        ]

        assert "mistral:latest" in models
        assert "llama2:7b" in models

    def test_ollama_keep_alive_parameter(self):
        """Keep alive parameter is configurable."""
        keep_alive = "5m"  # 5 minutes

        assert keep_alive in ["5m", "10m", "30m", "1h", "-1"]

    def test_ollama_num_ctx_parameter(self):
        """Context size (num_ctx) parameter is set."""
        context_window_size = 8192
        ollama_params = {}

        if context_window_size is not None:
            ollama_params["num_ctx"] = context_window_size

        assert ollama_params["num_ctx"] == 8192

    def test_ollama_repeat_penalty_parameter(self):
        """Repeat penalty parameter is configurable."""
        repeat_penalty = 1.1

        # Default is usually 1.1
        assert 1.0 <= repeat_penalty <= 2.0


class TestOllamaAvailability:
    """Tests for Ollama availability checks."""

    def test_ollama_is_available_responds_200(self):
        """Ollama available when API returns 200."""
        status_code = 200

        is_available = status_code == 200

        assert is_available

    def test_ollama_is_available_responds_non_200(self):
        """Ollama unavailable when API returns non-200."""
        status_codes = [400, 401, 403, 404, 500, 502, 503]

        for status_code in status_codes:
            is_available = status_code == 200
            assert not is_available, (
                f"Status {status_code} should be unavailable"
            )

    def test_ollama_is_available_connection_error(self):
        """Ollama unavailable on connection error."""
        connection_error = True

        if connection_error:
            is_available = False
        else:
            is_available = True

        assert not is_available

    def test_ollama_is_available_timeout(self):
        """Ollama unavailable on timeout."""
        timeout_error = True

        if timeout_error:
            is_available = False
        else:
            is_available = True

        assert not is_available

    def test_ollama_is_available_dns_resolution_failure(self):
        """Ollama unavailable on DNS failure."""
        error_message = "Name or service not known"

        if (
            "service not known" in error_message.lower()
            or "dns" in error_message.lower()
        ):
            is_available = False
        else:
            is_available = True

        assert not is_available

    def test_ollama_is_available_ssl_error(self):
        """Ollama unavailable on SSL error."""
        error_message = "SSL: CERTIFICATE_VERIFY_FAILED"

        if "ssl" in error_message.lower():
            is_available = False
        else:
            is_available = True

        assert not is_available

    def test_ollama_is_available_custom_port(self):
        """Ollama availability check uses custom port."""
        url = "http://localhost:8080"

        # Extract port
        port = url.split(":")[-1].split("/")[0]

        assert port == "8080"

    def test_ollama_is_available_ipv6_address(self):
        """Ollama supports IPv6 addresses."""
        url = "http://[::1]:11434"

        # IPv6 localhost
        assert "[::1]" in url

    def test_ollama_is_available_localhost_variants(self):
        """Various localhost variants are supported."""
        variants = [
            "http://localhost:11434",
            "http://127.0.0.1:11434",
            "http://[::1]:11434",
            "http://0.0.0.0:11434",
        ]

        for url in variants:
            # All should be valid localhost URLs
            assert (
                "localhost" in url
                or "127.0.0.1" in url
                or "::1" in url
                or "0.0.0.0" in url
            )

    def test_ollama_is_available_caching(self):
        """Availability check can be cached."""
        cache = {}
        cache_key = "ollama_available"

        # First check
        cache[cache_key] = True

        # Second check uses cache
        is_available = cache.get(cache_key)

        assert is_available


class TestOllamaModelParsing:
    """Tests for Ollama model name parsing."""

    def test_model_name_with_tag(self):
        """Model name with tag is parsed correctly."""
        model_name = "mistral:7b-instruct"

        parts = model_name.split(":")
        base_name = parts[0]
        tag = parts[1] if len(parts) > 1 else "latest"

        assert base_name == "mistral"
        assert tag == "7b-instruct"

    def test_model_name_without_tag(self):
        """Model name without tag defaults to latest."""
        model_name = "mistral"

        parts = model_name.split(":")
        base_name = parts[0]
        tag = parts[1] if len(parts) > 1 else "latest"

        assert base_name == "mistral"
        assert tag == "latest"

    def test_model_name_case_insensitive(self):
        """Model name matching is case insensitive."""
        model_name = "MISTRAL"
        available_models = ["mistral", "llama2"]

        found = model_name.lower() in [m.lower() for m in available_models]

        assert found

    def test_model_name_with_version(self):
        """Model name with version number is handled."""
        model_name = "llama2:13b-chat-q4_0"

        parts = model_name.split(":")
        base_name = parts[0]
        variant = parts[1] if len(parts) > 1 else "latest"

        assert base_name == "llama2"
        assert "13b" in variant


class TestOllamaErrorMessages:
    """Tests for Ollama error message handling."""

    def test_error_message_model_not_found(self):
        """Model not found error is user-friendly."""
        raw_error = "Error: model 'nonexistent' not found"

        if "not found" in raw_error.lower():
            user_message = (
                "The requested model is not available in Ollama. "
                "Please run 'ollama pull <model_name>' to download it."
            )
        else:
            user_message = raw_error

        assert "ollama pull" in user_message.lower()

    def test_error_message_service_unavailable(self):
        """Service unavailable error is user-friendly."""
        raw_error = "Error: status code: 503"

        if "503" in raw_error:
            user_message = (
                "Ollama service is temporarily unavailable. "
                "Please check that Ollama is running."
            )
        else:
            user_message = raw_error

        assert "unavailable" in user_message.lower()

    def test_error_message_connection_refused(self):
        """Connection refused error is user-friendly."""
        raw_error = "Connection refused: localhost:11434"

        if "connection refused" in raw_error.lower():
            user_message = (
                "Cannot connect to Ollama. "
                "Please ensure Ollama is running with 'ollama serve'."
            )
        else:
            user_message = raw_error

        assert "ollama serve" in user_message.lower()
