"""Unit-тесты для house_type_normalizer (#2007).

Покрывают:
- normalize_house_type(): yandex SCREAMING + cian camelCase вокабуляры → канон,
- идемпотентность (normalize(normalize(x)) == normalize(x)),
- None / '' / whitespace / 'other' / unknown → None.
"""

import pytest

from app.services.scrapers.house_type_normalizer import (
    _CANON,
    normalize_house_type,
)

# ── yandex SERP (SCREAMING_SNAKE buildingType) ───────────────────────────────


@pytest.mark.parametrize(
    ("raw", "expected"),
    [
        ("MONOLIT", "monolith"),
        ("BRICK", "brick"),
        ("PANEL", "panel"),
        ("MONOLIT_BRICK", "monolith_brick"),
        ("BLOCK", "block"),
        ("WOOD", "wood"),
    ],
)
def test_yandex_screaming_vocab(raw: str, expected: str) -> None:
    assert normalize_house_type(raw) == expected


# ── cian SERP (camelCase materialType) — reuse #2008 ─────────────────────────


@pytest.mark.parametrize(
    ("raw", "expected"),
    [
        ("monolith", "monolith"),
        ("brick", "brick"),
        ("panel", "panel"),
        ("block", "block"),
        ("wood", "wood"),
        ("monolithBrick", "monolith_brick"),
        ("gasSilicateBlock", "block"),
        ("aerocreteBlock", "block"),
        ("foamConcreteBlock", "block"),
        ("stalin", "brick"),
    ],
)
def test_cian_camelcase_vocab(raw: str, expected: str) -> None:
    assert normalize_house_type(raw) == expected


# ── регистронезависимость ────────────────────────────────────────────────────


@pytest.mark.parametrize(
    ("raw", "expected"),
    [
        ("monolit", "monolith"),  # lower yandex-token
        ("Brick", "brick"),
        ("MONOLITHBRICK", "monolith_brick"),
        ("  PANEL  ", "panel"),  # окружающие пробелы
    ],
)
def test_case_insensitive_and_strip(raw: str, expected: str) -> None:
    assert normalize_house_type(raw) == expected


# ── идемпотентность ──────────────────────────────────────────────────────────


@pytest.mark.parametrize("canon", sorted(_CANON))
def test_canonical_passthrough(canon: str) -> None:
    """Уже каноничное значение возвращается as-is (в т.ч. monolith_brick)."""
    assert normalize_house_type(canon) == canon


@pytest.mark.parametrize(
    "raw",
    [
        "MONOLIT",
        "MONOLIT_BRICK",
        "monolithBrick",
        "gasSilicateBlock",
        "stalin",
        "monolith_brick",
        "panel",
        "other",
        None,
        "",
    ],
)
def test_idempotency(raw: str | None) -> None:
    """normalize(normalize(x)) == normalize(x) для любого входа."""
    once = normalize_house_type(raw)
    assert normalize_house_type(once) == once


# ── None / unknown → None ────────────────────────────────────────────────────


@pytest.mark.parametrize("raw", [None, "", "   ", "other", "OTHER", "unknown", " keramzit "])
def test_unknown_returns_none(raw: str | None) -> None:
    """Неизвестное / 'other' / пустое → None (НЕ 'other'): NULL нейтрально для estimator."""
    assert normalize_house_type(raw) is None
