"""Testy jednostkowe Registry dla resources — analogicznie do test_registry.py."""

import pytest

from ..models import Backend, ResourceDescriptor
from ..registry import Registry


@pytest.fixture
def backend():
    return Backend(id="backend_a", url="http://localhost:8001/sse")


@pytest.fixture
def descriptor():
    return ResourceDescriptor(
        uri="test://greeting",
        name="greeting",
        description="Hello world resource",
        mime_type="text/plain",
    )


@pytest.fixture
def registry():
    return Registry()


def test_register_and_resolve_resource(registry, backend, descriptor):
    registry.add_backend(backend)
    registry.register_resource(backend, descriptor)

    mapping = registry.resolve_resource("test://greeting")
    assert mapping.public_uri == "test://greeting"
    assert mapping.original_uri == "test://greeting"
    assert mapping.backend == backend
    assert mapping.descriptor.mime_type == "text/plain"


def test_register_resource_with_custom_public_uri(registry, backend, descriptor):
    registry.add_backend(backend)
    registry.register_resource(backend, descriptor, public_uri="namespaced://x/greeting")

    mapping = registry.resolve_resource("namespaced://x/greeting")
    assert mapping.public_uri == "namespaced://x/greeting"
    assert mapping.original_uri == "test://greeting"


def test_resolve_unknown_resource_raises(registry):
    with pytest.raises(KeyError):
        registry.resolve_resource("test://nope")


def test_list_resources(registry, backend, descriptor):
    registry.add_backend(backend)
    registry.register_resource(backend, descriptor)

    resources = registry.list_resources()
    assert len(resources) == 1
    assert resources[0].public_uri == "test://greeting"


def test_remove_backend_clears_its_resources(registry, backend, descriptor):
    registry.add_backend(backend)
    registry.register_resource(backend, descriptor)

    registry.remove_backend("backend_a")

    assert registry.list_resources() == []


def test_remove_backend_resources_keeps_backend(registry, backend, descriptor):
    registry.add_backend(backend)
    registry.register_resource(backend, descriptor)

    registry.remove_backend_resources("backend_a")

    assert registry.list_resources() == []
    assert registry.has_backend("backend_a")


def test_remove_backend_leaves_other_resources(registry, descriptor):
    backend_a = Backend(id="a", url="http://localhost:8001/sse")
    backend_b = Backend(id="b", url="http://localhost:8002/sse")
    res_b = ResourceDescriptor(uri="test://b", name="b")

    registry.add_backend(backend_a)
    registry.add_backend(backend_b)
    registry.register_resource(backend_a, descriptor)
    registry.register_resource(backend_b, res_b)

    registry.remove_backend("a")

    resources = registry.list_resources()
    assert len(resources) == 1
    assert resources[0].public_uri == "test://b"


def test_uri_collision_raises(registry, descriptor):
    backend_a = Backend(id="a", url="http://localhost:8001/sse")
    backend_b = Backend(id="b", url="http://localhost:8002/sse")
    registry.add_backend(backend_a)
    registry.add_backend(backend_b)

    registry.register_resource(backend_a, descriptor)
    with pytest.raises(RuntimeError, match="collision"):
        registry.register_resource(backend_b, descriptor)

    # pierwsza rejestracja pozostaje nietknięta
    mapping = registry.resolve_resource("test://greeting")
    assert mapping.backend.id == "a"


def test_same_backend_can_re_register_resource(registry, backend, descriptor):
    """Re-rejestracja przez ten sam backend (np. po refresh) nie rzuca."""
    registry.add_backend(backend)
    registry.register_resource(backend, descriptor)
    registry.register_resource(backend, descriptor)
    assert len(registry.list_resources()) == 1
