import pytest

from app.sites.domain import DomainError, normalize_domain


@pytest.mark.parametrize(
    ("raw", "expected"),
    [
        ("exemple.fr", "exemple.fr"),
        ("  Exemple.FR  ", "exemple.fr"),
        ("https://exemple.fr/page?x=1#top", "exemple.fr"),
        ("http://www.exemple.fr/", "www.exemple.fr"),
        ("exemple.fr/chemin/profond", "exemple.fr"),
        ("château.fr", "xn--chteau-xta.fr"),
        ("xn--chteau-xta.fr", "xn--chteau-xta.fr"),
        ("sous.domaine.exemple.co.uk", "sous.domaine.exemple.co.uk"),
        # ccTLD IDN délégués dont les marques combinantes (Mn/Mc) rendent isalpha() faux :
        # la garde TLD doit donc s'appliquer après l'encodage, sur la forme ASCII.
        ("exemple.भारत", "exemple.xn--h2brj9c"),
        ("exemple.ලංකා", "exemple.xn--fzc2c9e2c"),
    ],
)
def test_normalize_domain_accepts(raw: str, expected: str) -> None:
    assert normalize_domain(raw) == expected


@pytest.mark.parametrize(
    "raw",
    [
        "",
        "   ",
        "https://user:pass@exemple.fr/",
        "exemple.fr:8080",
        "https://exemple.fr:8443/",
        "192.168.1.10",
        "[::1]",
        # Notations inet_aton : ip_address() les refuse (formes non strictes) mais
        # getaddrinfo — comme les navigateurs et curl — les résout en 127.0.0.1.
        "127.1",
        "0x7f.1",
        "0x7f.0.0.1",
        "exemple.123",
        # urlsplit lève un ValueError brut sur ces entrées : il doit devenir DomainError.
        "[::1",
        "exemple].fr",
        "[exemple.fr]",
        "ftp://exemple.fr/",
        "exemple",
        "localhost",
        "exemple.fr.",
        "exem ple.fr",
        "a..fr",
        "foo_bar.fr",
        "-bad.fr",
        "xn--zzzzzz.fr",
        "a" * 63 + "." + "b" * 63 + "." + "c" * 63 + "." + "d" * 63 + ".fr",
    ],
)
def test_normalize_domain_rejects(raw: str) -> None:
    with pytest.raises(DomainError):
        normalize_domain(raw)


def test_domain_error_is_a_value_error() -> None:
    # Attrapable comme ValueError (validators Pydantic, appels directs).
    assert issubclass(DomainError, ValueError)
