"""Framework auto-detection and patching."""
from __future__ import annotations

import importlib.util
import logging
import sys

logger = logging.getLogger("agentradar.auto_detect")

KNOWN_FRAMEWORKS = {
    "langgraph": "agentradar.instrumentation.langgraph",
}


def detect_and_patch() -> list[str]:
    """
    Scan for known frameworks and patch them.
    Returns list of framework names that were successfully patched.
    """
    patched = []
    attempted = set()

    # Check already-imported modules first
    for module_name, patcher_path in KNOWN_FRAMEWORKS.items():
        if module_name in sys.modules and patcher_path not in attempted:
            attempted.add(patcher_path)
            name = _try_patch(module_name, patcher_path)
            if name:
                patched.append(name)

    # Also check installed packages
    for module_name, patcher_path in KNOWN_FRAMEWORKS.items():
        if patcher_path in attempted:
            continue
        if _is_installed(module_name):
            attempted.add(patcher_path)
            name = _try_patch(module_name, patcher_path)
            if name:
                patched.append(name)

    if not patched:
        print(
            "agentradar: no known framework detected — "
            "auto-profiler active (all functions in your script will be traced)."
        )

    return patched


def _is_installed(module_name: str) -> bool:
    try:
        return importlib.util.find_spec(module_name) is not None
    except (ModuleNotFoundError, ValueError):
        return False


def _try_patch(module_name: str, patcher_path: str) -> str | None:
    try:
        import importlib
        patcher = importlib.import_module(patcher_path)
        success = patcher.patch()
        if success:
            display_name = _display_name(module_name)
            logger.debug("Patched %s", display_name)
            return display_name
        return None
    except Exception as e:
        logger.debug("Failed to patch %s: %s", module_name, e)
        _log_patch_failure(module_name, str(e))
        return None


def _display_name(module_name: str) -> str:
    names = {
        "langgraph": "LangGraph",
    }
    return names.get(module_name, module_name)


def _log_patch_failure(module_name: str, error: str) -> None:
    try:
        import os
        from pathlib import Path
        log_dir = Path.home() / ".agentradar"
        log_dir.mkdir(parents=True, exist_ok=True)
        log_file = log_dir / "patch_errors.log"
        from datetime import datetime
        with open(log_file, "a") as f:
            f.write(f"[{datetime.now().isoformat()}] Failed to patch {module_name}: {error}\n")
    except Exception:
        pass
