"""Tests for the unified segmentation-backend registry (classical / learned)."""
import numpy as np
import pytest
from sulcora.volume import Volume
from sulcora import seg_backends as SB
from sulcora.segmentation import BackendUnavailable


def _ct_clot(shape=(30, 30, 30)):
    d = np.full(shape, 30.0, np.float32)
    ii, jj, kk = np.meshgrid(*[np.arange(s) for s in shape], indexing="ij")
    d[(ii - 15) ** 2 + (jj - 15) ** 2 + (kk - 15) ** 2 <= 25] = 70.0    # hyperdense clot
    return Volume(d, np.eye(4))


def test_tasks_listed():
    t = SB.tasks()
    for k in ("hematoma", "tumor_enhancing", "tumor_flair", "vessels", "ventricles", "brain", "skull"):
        assert k in t


def test_classical_threshold_dispatch():
    vol = _ct_clot()
    mask = SB.segment(vol, "hematoma", method="threshold", hu_lo=45, hu_hi=100)
    assert set(np.unique(mask.data)).issubset({0, 1})
    assert int(mask.data.sum()) > 0


def test_model_method_without_registration_raises():
    vol = _ct_clot()
    if SB.has_model("hematoma"):
        pytest.skip("a model is registered for hematoma")
    with pytest.raises(BackendUnavailable):
        SB.segment(vol, "hematoma", method="model")


def test_register_model_and_use_it():
    vol = _ct_clot()
    sentinel = Volume(np.ones((30, 30, 30), np.uint8), np.eye(4))
    SB.register_model("hematoma", lambda v, **k: sentinel)
    try:
        assert SB.has_model("hematoma")
        out = SB.segment(vol, "hematoma", method="model")
        assert out is sentinel
    finally:
        SB._MODELS.pop("hematoma", None)          # keep global registry clean for other tests


def test_unknown_task_and_method():
    vol = _ct_clot()
    with pytest.raises(ValueError):
        SB.segment(vol, "bogus_task")
    with pytest.raises(ValueError):
        SB.segment(vol, "hematoma", method="bogus")
