"""Wrapper module around `lsprotocol.types`

This wrapper module is here to facility making `lsprotocol` optional
for -backports. When available, it is a (mostly) transparent wrapper
for the real module. When missing, it returns a placeholder object
for anything for the purpose of making things simpler.
"""

from types import GenericAlias
from typing import TYPE_CHECKING, Any
from collections.abc import Iterator

if TYPE_CHECKING:
    from lsprotocol import types

    # To defeat "unused" detections that might attempt to
    # optimize out the import
    assert types is not None
    __all__ = dir(types)

else:
    try:
        from lsprotocol import types

        __all__ = dir(types)

    except ImportError:

        stub_attr = {
            "__name__": __name__,
            "__file__": __file__,
            "__doc__": __doc__,
        }
        bad_attr = frozenset(
            [
                "pytestmark",
                "pytest_plugins",
            ]
        )

        class StubModule:
            @staticmethod
            def __getattr__(item: Any) -> Any:
                if item in stub_attr:
                    return stub_attr[item]
                if item in bad_attr:
                    raise AttributeError(item)
                if isinstance(item, str) and item.startswith("TEXT_"):
                    return str(item)
                return types

            def __or__(self, other) -> Any:
                if isinstance(other, StubModule):
                    return self.__class__
                if (
                    other is None
                    or isinstance(other, type)
                    or type(other) in (GenericAlias,)
                ):
                    return self.__class__ | other
                return NotImplemented

            # Order is not significant for `X | Y` when it is typing related
            # and that is the only thing we support.
            __ror__ = __or__

            def __call__(self, *args, **kwargs) -> Any:
                return self

            def __iter__(self) -> Iterator[Any]:
                return iter(())

        types = StubModule()
        __all__ = []


def __dir__() -> list[str]:
    return dir(types)


def __getattr__(name: str) -> Any:
    return getattr(types, name)
