from uuid import UUID

import pytest

from slices_typeid import base32

KNOWN_VECTORS = [
    (UUID("00000000-0000-0000-0000-000000000000").bytes, "00000000000000000000000000"),
    (UUID("019cb3d9-e9f8-79c0-a87d-08e8261dffc5").bytes, "01kjsxktfrf70agz88x0k1vzy5"),
    (UUID("a3f2dd47-b41f-4d69-85aa-96c51a2837d4").bytes, "53ybemfd0z9nmrbamprmd2gdym"),
    (UUID("71f6f4c2-faab-4f17-ad0d-bebcee272f15").bytes, "3hyvtc5ynb9wbtt3dyqkq2ebrn"),
    (UUID("207f47f4-2713-405a-a3bf-245a605bf24e").bytes, "10fx3z89rk81da7fs4b9g5qwje"),
    (UUID("4e9f5e91-df5d-42c8-acf5-31aaa918f73f").bytes, "2ekxf93qtx8b4asx9hnamhhxsz"),
]


@pytest.mark.parametrize(("byte_value", "base32_encoded_value"), KNOWN_VECTORS)
def test_encode_known_vectors(byte_value: bytes, base32_encoded_value: str):
    assert base32.encode(byte_value) == base32_encoded_value


@pytest.mark.parametrize(("byte_value", "base32_encoded_value"), KNOWN_VECTORS)
def test_decode_known_vectors(byte_value: bytes, base32_encoded_value: str):
    assert base32.decode(base32_encoded_value) == byte_value


@pytest.mark.parametrize(("byte_value", "base32_encoded_value"), KNOWN_VECTORS)
def test_base32_round_trip(byte_value: bytes, base32_encoded_value: str):
    assert base32.decode(base32.encode(byte_value)) == byte_value
    assert base32.encode(base32.decode(base32_encoded_value)) == base32_encoded_value


@pytest.mark.parametrize("payload", [b"", b"\x00" * 15, b"\x00" * 17])
def test_encode_rejects_invalid_lengths(payload: bytes):
    with pytest.raises(RuntimeError, match="Invalid length"):
        base32.encode(payload)


@pytest.mark.parametrize(
    ("base32_encoded_value", "message"),
    [
        ("", "Invalid length"),
        ("0" * 25, "Invalid length"),
        ("0" * 27, "Invalid length"),
        ("10fx3z89rk81da7fs4b9g5qwji", "Invalid base32 character"),
        ("10fx3z89rk81da7fs4b9g5qwjE", "Invalid base32 character"),
        ("10fx3z89rk81da7fs4b9g5qwj!", "Invalid base32 character"),
        ("i0fx3z89rk81da7fs4b9g5qwje", "Invalid base32 character"),
        ("80fx3z89rk81da7fs4b9g5qwje", "Invalid base32 starting character"),
    ],
)
def test_decode_rejects_invalid_input(base32_encoded_value: str, message: str):
    with pytest.raises(RuntimeError, match=message):
        base32.decode(base32_encoded_value)
