"""Smoke-test that all meshy modules can be imported.

Catches missing symbols, broken re-exports, and circular imports
that would otherwise only surface at runtime.
"""

import importlib
import pkgutil

import meshy

# Modules that need optional GI typelibs (Shumate, WebKit, etc.)
# or platform-specific frameworks (PyObjC) — skip when unavailable.
_OPTIONAL_DEPS = {"Shumate", "WebKit", "CoreBluetooth", "CoreLocation", "ServiceManagement", "objc"}


def _is_optional_dep_error(exc):
    msg = str(exc)
    if any(dep in msg for dep in _OPTIONAL_DEPS):
        return True
    if "g-resource-error-quark" in msg:
        return True
    return False


def _iter_meshy_modules():
    """Yield dotted names of all meshy submodules (recursive)."""
    prefix = meshy.__name__ + "."
    for info in pkgutil.walk_packages(meshy.__path__, prefix, onerror=lambda _name: None):
        yield info.name


def test_all_modules_importable():
    failures = {}
    for name in _iter_meshy_modules():
        try:
            importlib.import_module(name)
        except Exception as exc:
            if _is_optional_dep_error(exc):
                continue
            failures[name] = exc

    if failures:
        lines = [f"  {mod}: {err}" for mod, err in sorted(failures.items())]
        raise AssertionError(f"{len(failures)} module(s) failed to import:\n" + "\n".join(lines))
