"""Tests for ``mgf.apiprobe.core.matchers.semantic`` — IBAN, IMEI, E.164.

The differentiator vs. shape-only matchers: these tests prove the
matchers REJECT inputs that pass shape but fail validation
(corrupted IBAN check digits, IMEI failing Luhn).
"""

from __future__ import annotations

import pytest

from mgf.apiprobe.core.matchers.semantic import is_e164, is_iban, is_imei


class TestIsIban:
    @pytest.mark.parametrize(
        "value",
        [
            "GB82WEST12345698765432",  # canonical UK example (well-known valid IBAN)
            "DE89370400440532013000",  # canonical Germany example
            "FR1420041010050500013M02606",
            "GB82 WEST 1234 5698 7654 32",  # spaces tolerated
            "gb82west12345698765432",  # lowercase tolerated
        ],
    )
    def test_accepts_valid(self, value: str) -> None:
        assert is_iban()(value) is True

    def test_rejects_corrupted_check_digits(self) -> None:
        # Same shape as the canonical UK IBAN, but check digits flipped.
        # MOD-97 rejects.
        assert is_iban()("GB99WEST12345698765432") is False

    @pytest.mark.parametrize(
        "value",
        [
            "ZZ00BAD",  # too short
            "1234567890123456",  # no country code
            "GB82WEST123456987654",  # wrong length
            "",
            42,
        ],
    )
    def test_rejects_invalid_shape(self, value: object) -> None:
        assert is_iban()(value) is False


class TestIsImei:
    @pytest.mark.parametrize(
        "value",
        [
            # Canonical valid IMEIs (Luhn check passes)
            "490154203237518",
            "352099001761481",
        ],
    )
    def test_accepts_valid(self, value: str) -> None:
        assert is_imei()(value) is True

    def test_rejects_failing_luhn(self) -> None:
        # Same shape but flip the last digit — invalidates Luhn.
        assert is_imei()("490154203237519") is False

    @pytest.mark.parametrize(
        "value",
        [
            "12345678901234",  # 14 digits
            "1234567890123456",  # 16 digits
            "abc1234567890123",  # non-digits
            "",
            42,
        ],
    )
    def test_rejects_invalid_shape(self, value: object) -> None:
        assert is_imei()(value) is False


class TestIsE164:
    @pytest.mark.parametrize(
        "value",
        [
            "+12025551234",  # US number
            "+447911123456",  # UK
            "+966512345678",  # Saudi
            "+1",  # bare country code (1 digit min, 15 max)
        ],
    )
    def test_accepts_valid(self, value: str) -> None:
        assert is_e164()(value) is True

    @pytest.mark.parametrize(
        "value",
        [
            "12025551234",  # missing +
            "+0123456789",  # leading zero
            "+1234567890123456",  # 16 digits — over the cap
            "+",  # just plus
            "+1 202 555 1234",  # spaces
            "",
            42,
        ],
    )
    def test_rejects_invalid(self, value: object) -> None:
        assert is_e164()(value) is False
