"""
Behavioral tests for ssrf_validator module.

Tests the SSRF (Server-Side Request Forgery) validation functions.
"""


class TestIsIPBlockedLoopback:
    """Tests for loopback address blocking."""

    def test_127_0_0_1_blocked_by_default(self):
        """127.0.0.1 is blocked by default."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("127.0.0.1") is True

    def test_127_0_0_1_allowed_with_localhost_flag(self):
        """127.0.0.1 is allowed with allow_localhost=True."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("127.0.0.1", allow_localhost=True) is False

    def test_loopback_range_blocked(self):
        """Entire 127.x.x.x range is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("127.255.255.255") is True

    def test_ipv6_loopback_blocked(self):
        """IPv6 loopback ::1 is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("::1") is True

    def test_ipv6_loopback_allowed_with_flag(self):
        """IPv6 loopback allowed with allow_localhost=True."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("::1", allow_localhost=True) is False


class TestIsIPBlockedPrivate:
    """Tests for private IP address blocking."""

    def test_10_x_blocked(self):
        """10.x.x.x is blocked by default."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("10.0.0.1") is True

    def test_172_16_x_blocked(self):
        """172.16.x.x is blocked by default."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("172.16.0.1") is True

    def test_192_168_x_blocked(self):
        """192.168.x.x is blocked by default."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("192.168.1.1") is True

    def test_private_allowed_with_flag(self):
        """Private IPs allowed with allow_private_ips=True."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("10.0.0.1", allow_private_ips=True) is False
        assert is_ip_blocked("172.16.0.1", allow_private_ips=True) is False
        assert is_ip_blocked("192.168.1.1", allow_private_ips=True) is False


class TestIsIPBlockedCGNAT:
    """Tests for CGNAT (100.64.0.0/10) address handling."""

    def test_cgnat_blocked_by_default(self):
        """CGNAT range is blocked by default."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("100.64.0.1") is True

    def test_cgnat_allowed_with_private_flag(self):
        """CGNAT allowed with allow_private_ips=True."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("100.64.0.1", allow_private_ips=True) is False

    def test_cgnat_end_of_range(self):
        """End of CGNAT range is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("100.127.255.255") is True


class TestIsIPBlockedLinkLocal:
    """Tests for link-local address handling."""

    def test_link_local_blocked(self):
        """Link-local 169.254.x.x is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("169.254.0.1") is True

    def test_link_local_allowed_with_private_flag(self):
        """Link-local allowed with allow_private_ips=True (except AWS)."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        # Regular link-local should be allowed
        assert is_ip_blocked("169.254.1.1", allow_private_ips=True) is False


class TestIsIPBlockedAWSMetadata:
    """Tests for AWS metadata endpoint blocking."""

    def test_aws_metadata_always_blocked(self):
        """AWS metadata endpoint 169.254.169.254 is always blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        # Should be blocked even with all flags
        assert is_ip_blocked("169.254.169.254") is True
        assert is_ip_blocked("169.254.169.254", allow_localhost=True) is True
        assert is_ip_blocked("169.254.169.254", allow_private_ips=True) is True


class TestIsIPBlockedPublic:
    """Tests for public IP address handling."""

    def test_public_ip_not_blocked(self):
        """Public IPs are not blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("8.8.8.8") is False
        assert is_ip_blocked("1.1.1.1") is False
        assert is_ip_blocked("208.67.222.222") is False


class TestIsIPBlockedIPv6Private:
    """Tests for IPv6 private address handling."""

    def test_ipv6_fc00_blocked(self):
        """IPv6 fc00::/7 unique local is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("fc00::1") is True

    def test_ipv6_fd00_blocked(self):
        """IPv6 fd00:: unique local is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("fd00::1") is True

    def test_ipv6_fe80_blocked(self):
        """IPv6 fe80:: link-local is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("fe80::1") is True

    def test_ipv6_private_allowed_with_flag(self):
        """IPv6 private allowed with allow_private_ips=True."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("fc00::1", allow_private_ips=True) is False
        assert is_ip_blocked("fe80::1", allow_private_ips=True) is False


class TestIsIPBlockedInvalid:
    """Tests for invalid IP address handling."""

    def test_invalid_ip_not_blocked(self):
        """Invalid IP returns False (not blocked)."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("not-an-ip") is False

    def test_empty_string_not_blocked(self):
        """Empty string returns False."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("") is False

    def test_hostname_not_blocked(self):
        """Hostname is not blocked (not an IP)."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("example.com") is False


class TestIsIPBlockedZeroNetwork:
    """Tests for 0.0.0.0/8 network handling."""

    def test_0_0_0_0_blocked(self):
        """0.0.0.0 is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("0.0.0.0") is True

    def test_0_x_x_x_blocked(self):
        """0.x.x.x network is blocked."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("0.1.2.3") is True


class TestBlockedIPRanges:
    """Tests for BLOCKED_IP_RANGES constant."""

    def test_blocked_ranges_is_list(self):
        """BLOCKED_IP_RANGES is a list."""
        from local_deep_research.security.ssrf_validator import (
            BLOCKED_IP_RANGES,
        )

        assert isinstance(BLOCKED_IP_RANGES, list)

    def test_blocked_ranges_contains_loopback(self):
        """BLOCKED_IP_RANGES contains loopback."""
        import ipaddress
        from local_deep_research.security.ssrf_validator import (
            BLOCKED_IP_RANGES,
        )

        loopback = ipaddress.ip_network("127.0.0.0/8")
        assert loopback in BLOCKED_IP_RANGES

    def test_blocked_ranges_contains_rfc1918(self):
        """BLOCKED_IP_RANGES contains RFC1918 ranges."""
        import ipaddress
        from local_deep_research.security.ssrf_validator import (
            BLOCKED_IP_RANGES,
        )

        assert ipaddress.ip_network("10.0.0.0/8") in BLOCKED_IP_RANGES
        assert ipaddress.ip_network("172.16.0.0/12") in BLOCKED_IP_RANGES
        assert ipaddress.ip_network("192.168.0.0/16") in BLOCKED_IP_RANGES


class TestAllowedSchemes:
    """Tests for ALLOWED_SCHEMES constant."""

    def test_allowed_schemes_is_set(self):
        """ALLOWED_SCHEMES is a set."""
        from local_deep_research.security.ssrf_validator import ALLOWED_SCHEMES

        assert isinstance(ALLOWED_SCHEMES, set)

    def test_http_in_allowed(self):
        """http is in ALLOWED_SCHEMES."""
        from local_deep_research.security.ssrf_validator import ALLOWED_SCHEMES

        assert "http" in ALLOWED_SCHEMES

    def test_https_in_allowed(self):
        """https is in ALLOWED_SCHEMES."""
        from local_deep_research.security.ssrf_validator import ALLOWED_SCHEMES

        assert "https" in ALLOWED_SCHEMES


class TestAWSMetadataIP:
    """Tests for AWS_METADATA_IP constant."""

    def test_aws_metadata_ip_value(self):
        """AWS_METADATA_IP has correct value."""
        from local_deep_research.security.ssrf_validator import AWS_METADATA_IP

        assert AWS_METADATA_IP == "169.254.169.254"


class TestGetSafeUrl:
    """Tests for get_safe_url function."""

    def test_returns_url_if_safe(self):
        """Returns URL if it's safe."""
        from unittest.mock import patch

        from local_deep_research.security.ssrf_validator import get_safe_url

        with patch(
            "socket.getaddrinfo",
            return_value=[(2, 1, 6, "", ("93.184.216.34", 0))],
        ):
            result = get_safe_url("https://example.com")
        assert result == "https://example.com"

    def test_returns_none_for_empty(self):
        """Returns default for empty URL."""
        from local_deep_research.security.ssrf_validator import get_safe_url

        result = get_safe_url("")
        assert result is None

    def test_returns_default_for_empty(self):
        """Returns specified default for empty URL."""
        from local_deep_research.security.ssrf_validator import get_safe_url

        result = get_safe_url("", default="https://fallback.com")
        assert result == "https://fallback.com"

    def test_returns_none_for_none_input(self):
        """Returns default for None input."""
        from local_deep_research.security.ssrf_validator import get_safe_url

        result = get_safe_url(None)
        assert result is None


class TestValidateUrlNoBypass:
    """Tests that validate_url performs real validation (no test bypass)."""

    def test_localhost_blocked_by_default(self):
        """validate_url blocks localhost by default."""
        from local_deep_research.security.ssrf_validator import validate_url

        result = validate_url("http://127.0.0.1")
        assert result is False

    def test_testing_env_does_not_bypass(self, monkeypatch):
        """TESTING=true environment variable does NOT bypass validation."""
        from local_deep_research.security.ssrf_validator import validate_url

        monkeypatch.setenv("TESTING", "true")
        result = validate_url("http://127.0.0.1")
        assert result is False


class TestAllowLocalhostFlag:
    """Tests for allow_localhost flag interaction."""

    def test_localhost_not_blocked_with_flag(self):
        """Localhost is not blocked when allow_localhost=True."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("127.0.0.1", allow_localhost=True) is False
        assert is_ip_blocked("::1", allow_localhost=True) is False

    def test_private_still_blocked_with_localhost_flag(self):
        """Private IPs still blocked with allow_localhost (not allow_private)."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        # allow_localhost only allows loopback, not all private
        assert is_ip_blocked("10.0.0.1", allow_localhost=True) is True
        assert is_ip_blocked("192.168.1.1", allow_localhost=True) is True


class TestAllowPrivateIPsFlag:
    """Tests for allow_private_ips flag interaction."""

    def test_private_ips_includes_loopback(self):
        """allow_private_ips also allows loopback."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("127.0.0.1", allow_private_ips=True) is False

    def test_aws_metadata_still_blocked_with_private(self):
        """AWS metadata is still blocked even with allow_private_ips."""
        from local_deep_research.security.ssrf_validator import is_ip_blocked

        assert is_ip_blocked("169.254.169.254", allow_private_ips=True) is True
