from __future__ import annotations

import importlib
import operator
from typing import Callable

from cocotb_tools import _env


def load_entry() -> None:
    """Gather entry point information by parsing :envvar:`PYGPI_USERS`."""

    entry_points_str: list[str] = _env.get_list(
        "PYGPI_USERS",
        (
            "cocotb_tools._coverage:start_cocotb_library_coverage",
            "cocotb.logging:_configure",
            "cocotb._init:init_package_from_simulation",
            "cocotb.regression:_run_regression",
        ),
    )

    # Parse the entry point string of the form "module:func,module:func,...".
    # Any failure prevents any entry points from being loaded.
    entry_points: list[tuple[str, str]] = []
    try:
        for entry_point_str in entry_points_str:
            entry_module_str, entry_func_str = entry_point_str.split(":")
            # TODO maybe some basic validation of the module and function names.
            # WITHOUT IMPORTING THEM.
            entry_points.append((entry_module_str, entry_func_str))
    except Exception as e:
        raise RuntimeError(f"Failure to parse PYGPI_USERS {entry_point_str!r}") from e

    # Run all entry points.
    # Expect failure to stop the loading of any additional entry points.
    for entry_module_str, entry_func_str in entry_points:
        entry_module = importlib.import_module(entry_module_str)
        entry_func: Callable[[], object] = operator.attrgetter(entry_func_str)(
            entry_module
        )
        entry_func()
