"""Tests for url_utils module."""

import pytest

from local_deep_research.utilities.url_utils import normalize_url


class TestNormalizeUrl:
    """Tests for normalize_url function."""

    # Already proper URLs - should be returned unchanged
    def test_http_url_unchanged(self):
        """HTTP URLs should be returned unchanged."""
        url = "http://example.com"
        assert normalize_url(url) == "http://example.com"

    def test_https_url_unchanged(self):
        """HTTPS URLs should be returned unchanged."""
        url = "https://example.com"
        assert normalize_url(url) == "https://example.com"

    def test_http_url_with_port_unchanged(self):
        """HTTP URLs with port should be returned unchanged."""
        url = "http://localhost:8080"
        assert normalize_url(url) == "http://localhost:8080"

    def test_https_url_with_port_unchanged(self):
        """HTTPS URLs with port should be returned unchanged."""
        url = "https://example.com:443"
        assert normalize_url(url) == "https://example.com:443"

    def test_http_url_with_path_unchanged(self):
        """HTTP URLs with path should be returned unchanged."""
        url = "http://example.com/api/v1"
        assert normalize_url(url) == "http://example.com/api/v1"

    # Localhost handling - should get http://
    def test_localhost_gets_http(self):
        """localhost without scheme should get http://."""
        url = "localhost:11434"
        assert normalize_url(url) == "http://localhost:11434"

    def test_localhost_without_port_gets_http(self):
        """localhost without port should get http://."""
        url = "localhost"
        assert normalize_url(url) == "http://localhost"

    def test_127_0_0_1_gets_http(self):
        """127.0.0.1 should get http://."""
        url = "127.0.0.1:8080"
        assert normalize_url(url) == "http://127.0.0.1:8080"

    def test_0_0_0_0_gets_http(self):
        """0.0.0.0 should get http://."""
        url = "0.0.0.0:5000"
        assert normalize_url(url) == "http://0.0.0.0:5000"

    # External hosts - should get https://
    def test_external_host_gets_https(self):
        """External hosts without scheme should get https://."""
        url = "example.com"
        assert normalize_url(url) == "https://example.com"

    def test_external_host_with_port_gets_https(self):
        """External hosts with port should get https://."""
        url = "api.example.com:8443"
        assert normalize_url(url) == "https://api.example.com:8443"

    def test_external_host_with_path_gets_https(self):
        """External hosts with path should get https://."""
        url = "example.com/api"
        assert normalize_url(url) == "https://example.com/api"

    # Malformed scheme handling
    def test_http_colon_without_slashes(self):
        """http: without // should be fixed."""
        url = "http:example.com"
        assert normalize_url(url) == "http://example.com"

    def test_https_colon_without_slashes(self):
        """https: without // should be fixed."""
        url = "https:example.com"
        assert normalize_url(url) == "https://example.com"

    def test_http_colon_without_slashes_with_port(self):
        """http: without // but with port should be fixed."""
        url = "http:localhost:8080"
        assert normalize_url(url) == "http://localhost:8080"

    # Double slash handling
    def test_double_slash_prefix_localhost(self):
        """//localhost should be normalized with http://."""
        url = "//localhost:8080"
        assert normalize_url(url) == "http://localhost:8080"

    def test_double_slash_prefix_external(self):
        """//example.com should be normalized with https://."""
        url = "//example.com"
        assert normalize_url(url) == "https://example.com"

    # IPv6 handling
    def test_ipv6_localhost_gets_http(self):
        """IPv6 localhost [::1] should get http://."""
        url = "[::1]:8080"
        assert normalize_url(url) == "http://[::1]:8080"

    def test_ipv6_external_gets_https(self):
        """IPv6 external addresses should get https://."""
        url = "[2001:db8::1]:8080"
        assert normalize_url(url) == "https://[2001:db8::1]:8080"

    # Whitespace handling
    def test_strips_leading_whitespace(self):
        """Leading whitespace should be stripped."""
        url = "  http://example.com"
        assert normalize_url(url) == "http://example.com"

    def test_strips_trailing_whitespace(self):
        """Trailing whitespace should be stripped."""
        url = "http://example.com  "
        assert normalize_url(url) == "http://example.com"

    def test_strips_both_whitespace(self):
        """Both leading and trailing whitespace should be stripped."""
        url = "  example.com  "
        assert normalize_url(url) == "https://example.com"

    # Error handling
    def test_empty_string_raises_error(self):
        """Empty string should raise ValueError."""
        with pytest.raises(ValueError, match="URL cannot be empty"):
            normalize_url("")

    def test_none_raises_error(self):
        """None should raise an error (either ValueError or TypeError)."""
        with pytest.raises((ValueError, TypeError)):
            normalize_url(None)

    # Complex URLs
    def test_url_with_query_params(self):
        """URLs with query parameters should work."""
        url = "example.com/search?q=test&page=1"
        assert normalize_url(url) == "https://example.com/search?q=test&page=1"

    def test_url_with_fragment(self):
        """URLs with fragments should work."""
        url = "example.com/page#section"
        assert normalize_url(url) == "https://example.com/page#section"

    def test_url_with_auth(self):
        """URLs with authentication info should work."""
        url = "user:pass@example.com"
        assert normalize_url(url) == "https://user:pass@example.com"


class TestNormalizeUrlOllamaScenarios:
    """Tests for common Ollama URL scenarios."""

    def test_ollama_default_localhost(self):
        """Default Ollama localhost URL."""
        url = "localhost:11434"
        assert normalize_url(url) == "http://localhost:11434"

    def test_ollama_with_api_path(self):
        """Ollama URL with API path."""
        url = "localhost:11434/api/generate"
        assert normalize_url(url) == "http://localhost:11434/api/generate"

    def test_ollama_127_0_0_1(self):
        """Ollama on 127.0.0.1."""
        url = "127.0.0.1:11434"
        assert normalize_url(url) == "http://127.0.0.1:11434"

    def test_ollama_already_formatted(self):
        """Already properly formatted Ollama URL."""
        url = "http://localhost:11434"
        assert normalize_url(url) == "http://localhost:11434"
