"""Test URL utility functions."""

import pytest

from local_deep_research.utilities.url_utils import is_private_ip, normalize_url


class TestNormalizeUrl:
    """Test cases for the normalize_url function."""

    def test_localhost_without_scheme(self):
        """Test that localhost addresses get http:// prefix."""
        assert normalize_url("localhost:11434") == "http://localhost:11434"
        assert normalize_url("127.0.0.1:11434") == "http://127.0.0.1:11434"
        assert normalize_url("[::1]:11434") == "http://[::1]:11434"
        assert normalize_url("0.0.0.0:11434") == "http://0.0.0.0:11434"

    def test_external_host_without_scheme(self):
        """Test that external hosts get https:// prefix."""
        assert normalize_url("example.com:11434") == "https://example.com:11434"
        assert normalize_url("api.example.com") == "https://api.example.com"

    def test_private_ip_without_scheme(self):
        """Test that private network IPs get http:// prefix."""
        # 10.0.0.0/8 range
        assert normalize_url("10.0.0.1:8000") == "http://10.0.0.1:8000"
        assert (
            normalize_url("10.255.255.255:8000") == "http://10.255.255.255:8000"
        )
        # 172.16.0.0/12 range
        assert normalize_url("172.16.0.50:8000") == "http://172.16.0.50:8000"
        assert (
            normalize_url("172.31.255.255:8000") == "http://172.31.255.255:8000"
        )
        # 192.168.0.0/16 range
        assert (
            normalize_url("192.168.1.100:8000") == "http://192.168.1.100:8000"
        )
        assert (
            normalize_url("192.168.0.1:11434/v1")
            == "http://192.168.0.1:11434/v1"
        )
        # .local domain (mDNS)
        assert (
            normalize_url("myserver.local:8000") == "http://myserver.local:8000"
        )

    def test_malformed_url_with_scheme(self):
        """Test correction of malformed URLs like 'http:hostname'."""
        assert normalize_url("http:localhost:11434") == "http://localhost:11434"
        assert (
            normalize_url("https:example.com:11434")
            == "https://example.com:11434"
        )

    def test_well_formed_urls(self):
        """Test that well-formed URLs are unchanged."""
        assert (
            normalize_url("http://localhost:11434") == "http://localhost:11434"
        )
        assert (
            normalize_url("https://example.com:11434")
            == "https://example.com:11434"
        )
        assert (
            normalize_url("http://192.168.1.100:11434")
            == "http://192.168.1.100:11434"
        )

    def test_urls_with_double_slash_prefix(self):
        """Test URLs that start with //."""
        assert normalize_url("//localhost:11434") == "http://localhost:11434"
        assert (
            normalize_url("//example.com:11434") == "https://example.com:11434"
        )

    def test_empty_or_none_url(self):
        """Test handling of empty or None URLs."""
        with pytest.raises(ValueError):
            normalize_url("")
        with pytest.raises(ValueError):
            normalize_url(None)

    def test_url_with_path(self):
        """Test URLs with paths."""
        assert (
            normalize_url("localhost:11434/api") == "http://localhost:11434/api"
        )
        assert (
            normalize_url("example.com/api/v1") == "https://example.com/api/v1"
        )


class TestIsPrivateIp:
    """Test cases for the is_private_ip function."""

    def test_localhost_values(self):
        """Test that localhost values are recognized as private."""
        assert is_private_ip("localhost") is True
        assert is_private_ip("127.0.0.1") is True
        assert is_private_ip("[::1]") is True
        assert is_private_ip("0.0.0.0") is True

    def test_private_ipv4_ranges(self):
        """Test that private IPv4 ranges are recognized."""
        # 10.0.0.0/8
        assert is_private_ip("10.0.0.1") is True
        assert is_private_ip("10.255.255.255") is True
        # 172.16.0.0/12
        assert is_private_ip("172.16.0.1") is True
        assert is_private_ip("172.31.255.255") is True
        # 192.168.0.0/16
        assert is_private_ip("192.168.0.1") is True
        assert is_private_ip("192.168.255.255") is True

    def test_public_ipv4(self):
        """Test that public IPv4 addresses are not recognized as private."""
        assert is_private_ip("8.8.8.8") is False
        assert is_private_ip("1.1.1.1") is False
        assert (
            is_private_ip("172.32.0.1") is False
        )  # Just outside 172.16.0.0/12

    def test_hostnames(self):
        """Test hostname handling."""
        assert is_private_ip("api.openai.com") is False
        assert is_private_ip("example.com") is False
        assert is_private_ip("myserver.local") is True  # mDNS domain


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
