"""Tests for model registry loading and content."""

import pytest

from goodmem._registries import (
    EMBEDDER_MODEL_REGISTRY,
    LLM_MODEL_REGISTRY,
    RERANKER_MODEL_REGISTRY,
)


def test_embedder_registry_loads():
    assert isinstance(EMBEDDER_MODEL_REGISTRY, dict)
    assert len(EMBEDDER_MODEL_REGISTRY) > 0


def test_llm_registry_loads():
    assert isinstance(LLM_MODEL_REGISTRY, dict)
    assert len(LLM_MODEL_REGISTRY) > 0


def test_reranker_registry_loads():
    assert isinstance(RERANKER_MODEL_REGISTRY, dict)
    assert len(RERANKER_MODEL_REGISTRY) > 0


def test_known_embedder_has_expected_fields():
    entry = EMBEDDER_MODEL_REGISTRY["text-embedding-3-small"]
    assert entry["provider_type"] == "OPENAI"
    assert entry["dimensions"]["default"] == 1536
    assert "TEXT" in entry["supported_modalities"]


def test_known_llm_has_expected_fields():
    entry = LLM_MODEL_REGISTRY["gpt-4o"]
    assert entry["provider_type"] == "OPENAI"
    assert entry["max_context_length"] > 0
    assert "TEXT" in entry["supported_modalities"]


def test_known_reranker_has_expected_fields():
    entry = RERANKER_MODEL_REGISTRY["rerank-v3.5"]
    assert entry["provider_type"] == "COHERE"
    assert "TEXT" in entry["supported_modalities"]


def test_unknown_model_absent():
    assert "nonexistent-model-xyz" not in EMBEDDER_MODEL_REGISTRY
    assert "nonexistent-model-xyz" not in LLM_MODEL_REGISTRY
    assert "nonexistent-model-xyz" not in RERANKER_MODEL_REGISTRY


def test_embedder_default_dimensions_capped_at_1536():
    """All embedder default dimensions should be <= 1536."""
    for model_id, entry in EMBEDDER_MODEL_REGISTRY.items():
        dims = entry.get("dimensions")
        if dims and "default" in dims:
            assert dims["default"] <= 1536, (
                f"{model_id} default dimensions {dims['default']} exceeds 1536"
            )


# ---------------------------------------------------------------------------
# Regression: render.py REGISTRIES_DIR path (BUG-03)
# ---------------------------------------------------------------------------

def test_render_registries_dir_correct():
    """registries/render.py REGISTRIES_DIR must point to the registries dir."""
    from pathlib import Path
    render_path = Path(__file__).parent.parent / "goodmem" / "registries" / "render.py"
    source = render_path.read_text()
    assert 'Path(__file__).parent / "goodmem"' not in source, (
        "REGISTRIES_DIR must not append 'goodmem/registries' — the file is already there"
    )
    assert "REGISTRIES_DIR = Path(__file__).parent" in source, (
        "REGISTRIES_DIR should be Path(__file__).parent"
    )


# ---------------------------------------------------------------------------
# Regression: FRAG-01/02/03 — error handling on registry/convenience load
# ---------------------------------------------------------------------------

def test_registry_load_wraps_errors():
    """_load_registry must raise RuntimeError with context on bad files (FRAG-01)."""
    import inspect
    from goodmem._registries import _load_registry
    source = inspect.getsource(_load_registry)
    assert "RuntimeError" in source, (
        "_load_registry must raise RuntimeError with context on load failure"
    )
    assert "FileNotFoundError" in source or "JSONDecodeError" in source, (
        "_load_registry must catch FileNotFoundError or JSONDecodeError"
    )


def test_provider_endpoints_validates_keys():
    """PROVIDER_ENDPOINTS must validate that every provider has default_base_url (FRAG-02)."""
    import inspect
    import goodmem._registries as reg
    source = inspect.getsource(reg)
    assert '"default_base_url" not in' in source or "'default_base_url' not in" in source, (
        "PROVIDER_ENDPOINTS builder must check for missing default_base_url"
    )


def test_convenience_warns_on_missing_file():
    """Missing convenience.json must emit a warning, not silently disable (FRAG-03)."""
    import inspect
    from goodmem import _transforms
    source = inspect.getsource(_transforms)
    assert "warnings.warn" in source, (
        "_transforms must warn when convenience.json is missing"
    )


# ---------------------------------------------------------------------------
# Regression: PROTO-01 — ResultSetBoundary.kind must be Literal
# ---------------------------------------------------------------------------

def test_result_set_boundary_kind_is_literal():
    """ResultSetBoundary.kind must be Literal['BEGIN', 'END'], not bare str (PROTO-01)."""
    from goodmem.models.result_set_boundary import ResultSetBoundary
    ann = ResultSetBoundary.model_fields["kind"].annotation
    ann_str = str(ann)
    assert "Literal" in ann_str, (
        f"ResultSetBoundary.kind must be Literal, got {ann_str}"
    )
    assert "'BEGIN'" in ann_str and "'END'" in ann_str, (
        f"ResultSetBoundary.kind must include BEGIN and END, got {ann_str}"
    )


def test_render_guarded_by_main():
    """render.py CLI logic must be behind if __name__ == '__main__' (SURP-07)."""
    from pathlib import Path
    render_path = Path(__file__).parent.parent / "goodmem" / "registries" / "render.py"
    source = render_path.read_text()
    assert 'if __name__ == "__main__":' in source, (
        "render.py CLI must be guarded behind if __name__ == '__main__'"
    )


# ---------------------------------------------------------------------------
# Regression W10: Ping models removed
# ---------------------------------------------------------------------------

def test_ping_event_module_removed():
    """import goodmem.models.ping_event must raise ModuleNotFoundError."""
    import importlib
    with pytest.raises(ModuleNotFoundError):
        importlib.import_module("goodmem.models.ping_event")


def test_no_ping_names_in_models_dir():
    """No Ping* names should appear in dir(goodmem.models)."""
    import goodmem.models
    ping_names = [n for n in dir(goodmem.models) if n.startswith("Ping")]
    assert ping_names == [], (
        f"Ping names found in goodmem.models: {ping_names}"
    )
