"""Tests for pybyd._crypto.hashing.

Test vectors cross-validated against the Node.js implementation.
"""

from __future__ import annotations

from pybyd._crypto.hashing import compute_checkcode, md5_hex, sha1_mixed


class TestMd5Hex:
    def test_empty(self) -> None:
        assert md5_hex("") == "D41D8CD98F00B204E9800998ECF8427E"

    def test_simple(self) -> None:
        assert md5_hex("test") == "098F6BCD4621D373CADE4E832627B4F6"

    def test_hello_world(self) -> None:
        assert md5_hex("hello world") == "5EB63BBBE01EEED093CB22BB8F5ACDC3"

    def test_always_uppercase(self) -> None:
        result = md5_hex("anything")
        assert result == result.upper()
        assert len(result) == 32


class TestSha1Mixed:
    def test_known_vector_test(self) -> None:
        assert sha1_mixed("test") == "A94a8Fe5CCb19Ba61C4c873D391E987982fBBd3"

    def test_known_vector_hello(self) -> None:
        assert sha1_mixed("hello") == "AAf4C61dDCc5E8a2DAbeDEf3B482Cd9AEa9434d"

    def test_known_vector_empty(self) -> None:
        assert sha1_mixed("") == "DA39A3ee5E6b4Bd3255BFef95601890AFd879"

    def test_known_vector_complex(self) -> None:
        assert sha1_mixed("a=1&b=2&countryCode=NL&password=ABCDEF") == "68405243FA654845928251cd2Ae6B575D0362A92"

    def test_length_at_most_40(self) -> None:
        result = sha1_mixed("anything")
        assert len(result) <= 40


class TestComputeCheckcode:
    def test_simple(self) -> None:
        assert compute_checkcode({"key": "value"}) == "a0b7be50ddce808de0032747a7353f7c"

    def test_multi_field(self) -> None:
        payload = {"countryCode": "NL", "encryData": "ABCD", "identifier": "user"}
        assert compute_checkcode(payload) == "99be67c34c6450a22ec9d0420f8dc3b9"

    def test_length(self) -> None:
        result = compute_checkcode({"a": "b"})
        assert len(result) == 32

    def test_preserves_insertion_order(self) -> None:
        """Checkcode depends on JSON key order matching dict insertion order."""
        result1 = compute_checkcode({"a": "1", "b": "2"})
        result2 = compute_checkcode({"b": "2", "a": "1"})
        # Different key order -> different JSON -> different checkcode
        assert result1 != result2
