"""
Agenx integrations registry

Usage:
    import agenx.integrations as integrations
    integrations.instrument_all()

    from agenx.integrations import LangChainInstrumentor
    LangChainInstrumentor().instrument()
"""

from __future__ import annotations
import importlib

from ._base import BaseInstrumentor


_REGISTRY: dict[str, tuple[str, str, str]] = {
    "langchain": ("agenx.integrations.langchain", "LangChainInstrumentor", "langchain_core"),
}

_active: dict[str, BaseInstrumentor] = {}


def instrument(name: str) -> None:
    """Instrument a specific library by name."""
    if name not in _REGISTRY:
        raise ValueError(f"Unknown integration '{name}'. Available: {list(_REGISTRY)}")
    mod_path, cls_name, _ = _REGISTRY[name]
    inst = _load_instrumentor(name, mod_path, cls_name)
    inst.instrument()
    _active[name] = inst


def uninstrument(name: str) -> None:
    """Remove instrumentation for a specific library."""
    if name in _active:
        _active[name].uninstrument()
        del _active[name]


def instrument_all(skip: list[str] | None = None) -> list[str]:
    """
    Detect all installed agentic libraries and instrument them.

    Args:
        skip: list of integration names to skip, e.g. ["crewai"]

    Returns:
        List of integration names that were successfully instrumented.
    """
    skip = set(skip or [])
    instrumented = []

    for name, (mod_path, cls_name, pkg) in _REGISTRY.items():
        if name in skip:
            continue
        if importlib.util.find_spec(pkg) is None:
            continue
        try:
            instrumentor = _load_instrumentor(name, mod_path, cls_name)
            instrumentor.instrument()
            _active[name] = instrumentor
            instrumented.append(name)
        except Exception as e:
            import warnings
            warnings.warn(f"agenx: failed to instrument '{name}': {e}", stacklevel=2)

    return instrumented 


def uninstrument_all() -> None:
    """Remove all active instrumentation. Mainly useful in tests."""
    for inst in list(_active.values()):
        inst.uninstrument()
    _active.clear()


def _load_instrumentor(name: str, mod_path: str, cls_name: str) -> BaseInstrumentor:
    if name in _active:
        return _active[name]
    mod = importlib.import_module(mod_path)
    cls = getattr(mod, cls_name)
    return cls()


def __getattr__(name: str):
    for int_name, (mod_path, cls_name, _) in _REGISTRY.items():
        if cls_name == name:
            mod = importlib.import_module(mod_path)
            return getattr(mod, cls_name)
    raise AttributeError(f"module 'agenx.integrations' has no attribute '{name}'")

