"""Regression tests for the SSRF guard.

Covers the plain ranges and the v4-in-v6 smuggling bypass: a private/metadata
v4 target hidden inside a v6 address (v4-mapped ::ffff:, 6to4 2002::) used to
slip past the v6-only blocklist. Surfaced while running the OPENSAGE
comprehension-gap probe against this module.
"""

import pytest

from backend.apps.agents.tools.ssrf_guard import SSRFBlocked, p_is_forbidden_ip, assert_safe_url


@pytest.mark.parametrize(
    "ip_str, forbidden",
    [
        # plain ranges still behave
        ("10.0.0.1", True),
        ("169.254.169.254", True),            # cloud metadata
        ("8.8.8.8", False),                   # public
        ("127.0.0.1", False),                 # loopback intentionally allowed
        ("::1", False),                       # v6 loopback allowed
        ("2606:4700::1", False),              # public v6
        ("fe80::1", True),                    # v6 link-local
        ("not-an-ip", True),                  # unparseable -> block
        # the bypass: a v4 target smuggled inside a v6 address
        ("::ffff:10.0.0.1", True),            # v4-mapped private
        ("::ffff:169.254.169.254", True),     # v4-mapped cloud metadata
        ("2002:0a00:0001::1", True),          # 6to4 of 10.0.0.1
        ("::ffff:127.0.0.1", False),          # v4-mapped loopback stays allowed
        ("::ffff:8.8.8.8", False),            # v4-mapped public stays allowed
    ],
)
def testp_is_forbidden_ip(ip_str, forbidden):
    assert p_is_forbidden_ip(ip_str) is forbidden


@pytest.mark.asyncio
async def test_assert_safe_url_blocks_v4_mapped_metadata():
    # IP-literal host short-circuits before DNS, so this needs no network.
    with pytest.raises(SSRFBlocked):
        await assert_safe_url("http://[::ffff:169.254.169.254]/latest/meta-data/")


@pytest.mark.asyncio
async def test_assert_safe_url_allows_v4_mapped_loopback():
    # App Builder previews on loopback must keep working, even v4-mapped.
    url = "http://[::ffff:127.0.0.1]:8731/"
    assert await assert_safe_url(url) == url
