from types import SimpleNamespace

import pytest

from kernel_service.registry import (
    ModelCapabilities,
    ModelRegistry,
    register_model,
    get_registry,
)


class DummyModel:
    """Simple stub that satisfies CXRModel protocol."""

    def __init__(self):
        self.analyzed_claims = []

    def analyze(self, claim, tenant_id):
        self.analyzed_claims.append((claim, tenant_id))
        return {"verdict": "approved"}


def _caps(**kwargs):
    defaults = dict(
        fusion_planes=3,
        uses_monte_carlo=False,
        uses_all_contexts=False,
        speed_profile="balanced",
        precision_level="standard",
        compliance_focus=False,
    )
    defaults.update(kwargs)
    return ModelCapabilities(**defaults)


def test_register_and_get_model(reset_registry):
    register_model("dummy", DummyModel, _caps(), singleton=True)
    registry = get_registry()

    model = registry.get_model("dummy")
    assert isinstance(model, DummyModel)


def test_register_duplicate_warns(reset_registry, capsys):
    register_model("dup", DummyModel, _caps())
    register_model("dup", DummyModel, _caps())
    captured = capsys.readouterr().out
    assert "model.reregistered" in captured


def test_get_model_not_found(reset_registry):
    registry = get_registry()
    with pytest.raises(ValueError):
        registry.get_model("unknown")


def test_default_model_roundtrip(reset_registry):
    register_model("m1", DummyModel, _caps())
    register_model("m2", DummyModel, _caps())

    registry = get_registry()
    registry.set_default("m2")
    assert registry.get_model().analyze({}, "tenant")["verdict"] == "approved"


def test_set_default_unknown_model(reset_registry):
    register_model("known", DummyModel, _caps())
    registry = get_registry()

    with pytest.raises(ValueError):
        registry.set_default("missing")


def test_list_models_and_capabilities(reset_registry):
    register_model("caps", DummyModel, _caps(fusion_planes=7))
    registry = get_registry()

    caps = registry.get_capabilities("caps")
    assert caps.fusion_planes == 7

    catalog = registry.list_models()
    assert "caps" in catalog
    assert catalog["caps"].fusion_planes == 7


def test_singleton_instances_are_reused(reset_registry):
    register_model("single", DummyModel, _caps(), singleton=True)
    registry = get_registry()

    first = registry.get_model("single")
    second = registry.get_model("single")
    assert first is second


def test_non_singleton_instances_are_new(reset_registry):
    register_model("transient", DummyModel, _caps(), singleton=False)
    registry = get_registry()

    first = registry.get_model("transient")
    second = registry.get_model("transient")
    assert first is not second

