"""Options for the AMTLK package.

In general, these options are not intended for functional differences but
more for any output generated by the package, such as rich or logging.
"""
from __future__ import annotations

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

from amltk._doc import sklearn_link_generator


class AMLTKOptions(TypedDict):
    """The options available for AMTLK.

    ```python exec="true" source="material-block" result="python"
    from amltk import options

    print(options)
    ```
    """

    rich_signatures: bool
    """Whether to display full signatures in rich output."""

    rich_link: Literal["auto", False]
    """Whether to use links in rich output."""

    links: dict[str, str | Callable[[str], str]]
    """The links to use in rich output.

    The keys are the names of the packages, and the values are either the
    direct link to use or a callable that takes the fully qualified name
    of the object and returns the link to use.
    """

    root_event_manager_name: str


_amltk_options: AMLTKOptions = {
    "rich_signatures": True,
    "rich_link": "auto",
    "links": {"sklearn": sklearn_link_generator},
    "root_event_manager_name": "amltk.root.eventmanager",
}

T = TypeVar("T")


@overload
def get_option(name: str, default: None = None) -> Any | None:
    ...


@overload
def get_option(name: str, default: T) -> Any | T:
    ...


def get_option(name: str, default: T | None = None) -> Any | T | None:
    """Get an option.

    ```python exec="true" source="material-block" result="python"
    from amltk import options

    print(options.get_option("rich_signatures"))
    ```
    """
    return _amltk_options.get(name, default)
