from collections.abc import Callable
from typing import Any, Literal, Never, TypeGuard, TypeVar, overload

from remedapy.decorator import make_data_last

T = TypeVar('T')
Empty = list[Never] | Literal[''] | tuple[()] | dict[Never, Never] | set[Never]


@overload
def is_empty() -> Callable[[Any], TypeGuard[Empty]]: ...


@overload
def is_empty(data: Any, /) -> TypeGuard[Empty]: ...


@make_data_last
def is_empty(data: Any, /) -> TypeGuard[Empty]:
    """
    A function that checks if the passed parameter is empty and narrows its type accordingly.

    Empty are:
    - [] (list)
    - '' (string)
    - () (tuple)
    - {} (dictionary)
    - set() (set)

    Parameters
    ----------
    data: Any
        Value to check.

    Returns
    -------
    TypeGuard[Empty]
        Whether the value passed is empty.

    Examples
    --------
    Data first:
    >>> R.is_empty([])
    True
    >>> R.is_empty(range(10))
    False

    Data last:
    >>> R.is_empty()([])
    True
    >>> R.is_empty()([1])
    False

    """
    return data in [[], '', (), {}, set()]
