"""The portable primitives, pinned so the TypeScript port has vectors to hit."""

from __future__ import annotations

from alert_triage.rng import (
    XorShift32,
    civil_from_days,
    days_from_civil,
    days_in_month,
    fnv1a32,
    iso_date,
)

# fnv1a32 over the decimal seed — identical to wordle_five's and to engine.ts.
FNV_VECTORS = {"0": 0x350CA8AF, "1": 0x340CA71C, "42": 0x87E38583, "4095": 0x43875F5F}


def test_fnv1a_vectors() -> None:
    for text, expect in FNV_VECTORS.items():
        assert fnv1a32(text) == expect, text


def test_xorshift_sequence_is_pinned() -> None:
    rng = XorShift32(fnv1a32("0"))
    first = [rng.next() for _ in range(5)]
    assert first == XORSHIFT_FROM_SEED_0


XORSHIFT_FROM_SEED_0 = [2738490563, 3068243922, 3765331391, 3085691315, 2439018365]


def test_zero_seed_is_replaced() -> None:
    assert XorShift32(0).state != 0


def test_sample_is_distinct_and_partial_shuffle() -> None:
    rng = XorShift32(7)
    out = rng.sample(list(range(10)), 4)
    assert len(out) == 4 and len(set(out)) == 4


def test_civil_dates_round_trip() -> None:
    for day in range(days_from_civil(1999, 12, 25), days_from_civil(2030, 3, 2)):
        y, m, d = civil_from_days(day)
        assert days_from_civil(y, m, d) == day


def test_known_dates() -> None:
    assert days_from_civil(1970, 1, 1) == 0
    assert iso_date(days_from_civil(2026, 3, 1)) == "2026-03-01"
    assert days_in_month(2024, 2) == 29 and days_in_month(2026, 2) == 28
    assert days_in_month(2026, 12) == 31
