"""Tests for SSRF protection in safe_source.validate_image_url."""

import pytest
from fastapi import HTTPException

from ledgrab.utils.safe_source import validate_image_url


@pytest.mark.parametrize(
    "url",
    [
        "http://127.0.0.1/",
        "http://127.0.0.1:8080/x.png",
        "http://[::1]/",
        "http://169.254.169.254/latest/meta-data/",
        "http://10.0.0.1/",
        "http://192.168.1.1/x.png",
        "http://172.16.0.5/",
        "http://0.0.0.0/",
        "http://224.0.0.1/",  # multicast
        "ftp://example.com/",
        "file:///etc/passwd",
        "gopher://example.com/",
        "http:///no-host",
    ],
)
def test_validate_image_url_rejects_dangerous_targets(url):
    with pytest.raises(HTTPException) as exc:
        validate_image_url(url)
    assert exc.value.status_code == 400


def test_validate_image_url_accepts_public(monkeypatch):
    """Accept a public host whose DNS resolves to a non-private IP."""
    import ledgrab.utils.safe_source as ss

    def fake_getaddrinfo(host, _port):
        # Pretend example.com resolves to a public IP
        return [(0, 0, 0, "", ("93.184.216.34", 0))]

    monkeypatch.setattr(ss.socket, "getaddrinfo", fake_getaddrinfo)
    # Should not raise
    validate_image_url("https://example.com/image.png")


def test_validate_image_url_blocks_dns_to_private(monkeypatch):
    """Hostname that resolves to a private IP must be rejected."""
    import ledgrab.utils.safe_source as ss

    def fake_getaddrinfo(host, _port):
        return [(0, 0, 0, "", ("10.0.0.5", 0))]

    monkeypatch.setattr(ss.socket, "getaddrinfo", fake_getaddrinfo)
    with pytest.raises(HTTPException) as exc:
        validate_image_url("http://internal.example.com/")
    assert exc.value.status_code == 400
