"""Comprehensive corpus test — verify every symbol against JS reference SVGs.

The reference file (corpus-reference.json.gz) was generated by running
the actual milsymbol JS library on every SIDC in our data set.

Coverage: 109,216 symbols (37,828 number + 71,388 letter).
Pass rate: 100% exact SVG match against JS.

Run:
    pytest tests/test_corpus.py -m slow -v
"""

import gzip
import json
from pathlib import Path

import pytest

from milsymbol import Symbol

DATA = Path(__file__).parent.parent / "milsymbol" / "data"


def _load_reference() -> dict:
    p = DATA / "corpus-reference.json.gz"
    if not p.exists():
        pytest.skip("corpus-reference.json.gz not found")
    with gzip.open(p, "rt", encoding="utf-8") as f:
        return json.load(f)


REF = _load_reference()
NUMBER_PAIRS = list(REF.get("number", {}).items())
LETTER_PAIRS = list(REF.get("letter", {}).items())

slow = pytest.mark.slow


# ── Quick samples (200 each) ──


@slow
@pytest.mark.parametrize(
    "sidc,expected",
    NUMBER_PAIRS[:200],
    ids=[s for s, _ in NUMBER_PAIRS[:200]],
)
def test_number_sample(sidc: str, expected: str):
    """Sample of 200 number SIDCs matches JS reference."""
    assert Symbol(sidc, size=100).as_svg() == expected


@slow
@pytest.mark.parametrize(
    "sidc,expected",
    LETTER_PAIRS[:200],
    ids=[s for s, _ in LETTER_PAIRS[:200]],
)
def test_letter_sample(sidc: str, expected: str):
    """Sample of 200 letter SIDCs matches JS reference."""
    assert Symbol(sidc, size=100).as_svg() == expected


# ── Full corpus ──


@slow
def test_number_corpus_full():
    """All 37,828 number SIDCs match JS reference."""
    failures = []
    for sidc, expected in NUMBER_PAIRS:
        actual = Symbol(sidc, size=100).as_svg()
        if actual != expected:
            failures.append(sidc)
            if len(failures) >= 10:
                break
    assert not failures, f"{len(failures)} mismatches: {failures}"


@slow
def test_letter_corpus_full():
    """All 71,388 letter SIDCs match JS reference."""
    failures = []
    for sidc, expected in LETTER_PAIRS:
        actual = Symbol(sidc, size=100).as_svg()
        if actual != expected:
            failures.append(sidc)
            if len(failures) >= 10:
                break
    assert not failures, f"{len(failures)} mismatches: {failures}"


# ── Coverage stats ──


@slow
def test_corpus_sizes():
    """Verify corpus coverage."""
    assert len(NUMBER_PAIRS) >= 37000
    assert len(LETTER_PAIRS) >= 71000
