"""Module autoload helpers."""

import importlib
from pathlib import Path
from types import ModuleType
from typing import Any


class ModuleAutoloadError(ImportError):
    """Raised when module import fails during autoload."""

    def __init__(self, module_name: str) -> None:
        super().__init__(f"Could not import module '{module_name}' during autoload.")
        self.module_name = module_name


def _validate_package(package: Any) -> None:
    if not hasattr(package, "__name__") or not hasattr(package, "__path__"):
        raise TypeError("autoload requires an imported package object with __name__ and __path__")


def _iter_modules(package: Any) -> list[str]:
    module_names: list[str] = []
    for base_path in sorted(str(path) for path in package.__path__):
        base = Path(base_path)
        for path in sorted(base.rglob("*.py")):
            if path.name == "__init__.py":
                continue
            relative_parts = path.relative_to(base).with_suffix("").parts
            module_names.append(".".join((package.__name__, *relative_parts)))
    return module_names


def autoload(package: Any) -> tuple[ModuleType, ...]:
    """Import every module under a package."""

    _validate_package(package)
    modules: list[ModuleType] = []
    for module_name in _iter_modules(package):
        try:
            modules.append(importlib.import_module(module_name))
        except Exception as exc:
            raise ModuleAutoloadError(module_name) from exc
    return tuple(modules)


__all__ = ["ModuleAutoloadError", "autoload"]
