"""Tests for canonicalization — normalize_key, validate_proposed_key, open catalog."""

from __future__ import annotations

from arandu.constants import ALLOWED_ATTRIBUTE_KEYS, ATTRIBUTE_ALIASES
from arandu.write.canonicalization import (
    _build_dotted_variant_map,
    normalize_key,
    validate_proposed_key,
)

# ---------------------------------------------------------------------------
# normalize_key
# ---------------------------------------------------------------------------


def test_normalize_key_basic():
    """Lowercase, strip, dots."""
    assert normalize_key("User Identity Name") == "user.identity.name"


def test_normalize_key_hyphens():
    """Hyphens → dots."""
    assert normalize_key("user-home-city") == "user.home.city"


def test_normalize_key_underscores_preserved():
    """Underscores are kept (legitimate separators)."""
    assert normalize_key("user.identity.birth_date") == "user.identity.birth_date"


def test_normalize_key_empty():
    """Empty string → empty."""
    assert normalize_key("") == ""


def test_normalize_key_collapse_dots():
    """Multiple dots collapsed."""
    assert normalize_key("user...home..city") == "user.home.city"


def test_normalize_key_strip_dots():
    """Leading/trailing dots stripped."""
    assert normalize_key(".user.name.") == "user.name"


# ---------------------------------------------------------------------------
# validate_proposed_key
# ---------------------------------------------------------------------------


def test_validate_valid_key():
    """Well-formed key in allowed namespace."""
    assert validate_proposed_key("user.identity.nickname") is True


def test_validate_unknown_namespace():
    """Unknown namespace → invalid."""
    assert validate_proposed_key("unknown.field.name") is False


def test_validate_extra_namespace():
    """Deployer-provided extra namespace should be accepted."""
    assert validate_proposed_key("finance.income.monthly", extra_namespaces={"finance"}) is True
    assert validate_proposed_key("finance.income.monthly") is False  # without extra


def test_validate_too_long():
    """Key exceeding max length → invalid."""
    assert validate_proposed_key("user." + "a" * 100) is False


def test_validate_empty():
    """Empty string → invalid."""
    assert validate_proposed_key("") is False


def test_validate_special_chars():
    """Special characters → invalid."""
    assert validate_proposed_key("user.name!@#") is False


# ---------------------------------------------------------------------------
# Dotted variant map
# ---------------------------------------------------------------------------


def test_dotted_variant_map_with_keys():
    """birth_date should produce dotted variant when keys are provided."""
    keys = {"user.identity.birth_date", "user.home.zip_code"}
    m = _build_dotted_variant_map(keys)
    assert "user.identity.birth.date" in m
    assert m["user.identity.birth.date"] == "user.identity.birth_date"


def test_dotted_variant_map_empty_keys():
    """Empty keys → empty map."""
    m = _build_dotted_variant_map(set())
    assert m == {}


# ---------------------------------------------------------------------------
# Constants are empty by default (open catalog)
# ---------------------------------------------------------------------------


def test_allowed_keys_empty_default():
    """ALLOWED_ATTRIBUTE_KEYS should be empty by default."""
    assert set() == ALLOWED_ATTRIBUTE_KEYS


def test_attribute_aliases_empty_default():
    """ATTRIBUTE_ALIASES should be empty by default."""
    assert ATTRIBUTE_ALIASES == {}
