"""Unit tests for unit systems API (unxt_api._unitsystems)."""

import plum

import unxt_api as uapi

# ==============================================================================
# Tests for unitsystem_of()
# ==============================================================================


def test_unitsystem_of_is_abstract_dispatch() -> None:
    """Test that unitsystem_of is an abstract dispatch function."""
    assert isinstance(uapi.unitsystem_of, plum.function.Function)
    assert hasattr(uapi.unitsystem_of, "methods")


def test_unitsystem_of_accepts_any_type() -> None:
    """Test that unitsystem_of accepts Any type in signature."""
    assert "unitsystem_of" in dir(uapi)


def test_unitsystem_of_no_default_implementation() -> None:
    """Test that calling unitsystem_of without implementation may return a default.

    Note: When unxt is imported (e.g., during doctest execution), it may
    register a default implementation that returns a system for unknown types.
    """

    class NoDispatchType:
        pass

    obj = NoDispatchType()

    try:
        result = uapi.unitsystem_of(obj)
        # If it doesn't raise, unxt has provided a default implementation
        # (typically returns DimensionlessUnitSystem or None)
        assert result is not None or result is None
    except plum.resolver.NotFoundLookupError:
        # This is also acceptable if unxt hasn't been imported
        pass


def test_unitsystem_of_can_register_custom_dispatch(custom_quantity_type) -> None:
    """Test that custom dispatches can be registered."""

    class MockUnitSystem:
        def __init__(self, name: str) -> None:
            self.name = name

    @plum.dispatch
    def unitsystem_of(obj: custom_quantity_type, /) -> MockUnitSystem:
        return MockUnitSystem("SI")

    quantity = custom_quantity_type(42, "m")
    result = unitsystem_of(quantity)

    assert isinstance(result, MockUnitSystem)
    assert result.name == "SI"


def test_unitsystem_of_multiple_dispatches_possible() -> None:
    """Test that multiple dispatches can coexist."""
    initial_count = len(uapi.unitsystem_of.methods)
    assert initial_count >= 0


# ==============================================================================
# API consistency tests
# ==============================================================================


def test_unitsystem_of_is_exported() -> None:
    """Test that unitsystem_of is exported from unxt_api."""
    assert hasattr(uapi, "unitsystem_of")


def test_unitsystem_of_in_all() -> None:
    """Test that unitsystem_of is in __all__."""
    assert "unitsystem_of" in uapi.__all__


def test_unitsystem_of_is_dispatch_function() -> None:
    """Test that unitsystem_of is a dispatch function."""
    assert isinstance(uapi.unitsystem_of, plum.function.Function)
