# __init__.py — lazy public API from _func_*.py modules; robust for wheels
from __future__ import annotations

import os as _os
import pkgutil as _pkgutil
import importlib as _importlib
from typing import Iterable as _Iterable

__all__: list[str] = []

# ---------------------------
# version
# ---------------------------
try:
    from ._version import __version__
except Exception:
    __version__ = "unknown"
__all__.append("__version__")

# ---------------------------
# pure-Python helpers (safe to import now)
# ---------------------------
try:
    from ._func_repsim import repsim_kernels, repsim_hsic  # no _repsim needed

    __all__ += ["repsim_kernels", "repsim_hsic"]
except Exception:
    # Leave helpers out if the module is absent; not fatal.
    pass


# ---------------------------
# lazy wrappers for _func_* modules
# ---------------------------
def _unique(seq: Iterable[str]) -> list[str]:
    seen, out = set(), []
    for s in seq:
        if s not in seen:
            seen.add(s)
            out.append(s)
    return out


def _lazy_call(modname: str, funcname: str):
    """Create a function that imports `.modname` and calls `funcname`."""

    def _wrapper(*args, **kwargs):
        # Import on first use — avoids circular import with _repsim at package init
        mod = _importlib.import_module(f".{modname}", __name__)
        fn = getattr(mod, funcname)
        return fn(*args, **kwargs)

    _wrapper.__name__ = funcname
    _wrapper.__qualname__ = funcname
    _wrapper.__doc__ = f"Lazy wrapper for repsim.{funcname} (defined in {modname})."
    return _wrapper


# Discover _func_*.py modules without importing them
_func_modules = [
    m.name
    for m in _pkgutil.iter_modules(list(__path__))
    if (not m.ispkg) and m.name.startswith("_func_")
]

# For each _func_foo module, expose a `foo` symbol that lazily imports and calls it.
for _stem in sorted(set(_func_modules)):
    if _stem == "_func_repsim":
        continue  # already handled above
    _funcname = _stem.replace("_func_", "", 1)
    # Attach wrapper only if not colliding with existing names
    if _funcname not in globals():
        globals()[_funcname] = _lazy_call(_stem, _funcname)
        __all__.append(_funcname)

# finalize public API
__all__ = _unique(__all__)

# -------- cleanup internals from namespace --------
for _name in [
    "_os",
    "_pkgutil",
    "_importlib",
    "_Iterable",
    "_unique",
    "_lazy_call",
    "_func_modules",
    "_stem",
    "_funcname",
    "annotations",
]:
    globals().pop(_name, None)
del _name
