from collections.abc import Callable
from typing import TypeVar, overload

from remedapy.decorator import make_data_last

T = TypeVar('T')
Fallback = TypeVar('Fallback')


@overload
def default_to(data: T | None, fallback: Fallback, /) -> T | Fallback: ...


@overload
def default_to(fallback: Fallback, /) -> Callable[[T | None], T | Fallback]: ...


@make_data_last
def default_to(
    value: T | None,
    fallback: Fallback,
    /,
) -> T | Fallback:
    """
    Given two values, returns the first if it is not None, otherwise the second.

    Parameters
    ----------
    value : T | None
        Value check for being None (positional-only).
    fallback: Fallback
        Value to return if the first is None (positional-only).

    Returns
    -------
    T | Fallback
        First value if it is not None, otherwise the second.

    Examples
    --------
    Data first:
    >>> R.default_to('hello', 'world')
    'hello'
    >>> R.default_to(None, 'world')
    'world'

    Data last:
    >>> R.pipe('hello', R.default_to('world'))
    'hello'
    >>> R.pipe(None, R.default_to('world'))
    'world'

    """
    return value if value is not None else fallback
