"""
Auto-instrumentation module for Aigie SDK.

This module provides automatic instrumentation for:
- LangChain agents and chains
- LangGraph workflows
- Browser-Use browser automation
- Claude Agent SDK sessions
- Google ADK agents
- Strands agents
- DSPy modules
- LLM clients (OpenAI, Anthropic, Gemini)
- Tool calls
- Automatic trace creation

Usage:
    from aigie import Aigie

    # Simple init - automatically enables all instrumentation
    aigie = Aigie(api_url="https://app.aigie.io/api", api_key="your-key")
    await aigie.initialize()

    # All frameworks are now automatically traced
"""

import os
from typing import Optional

_instrumentation_state = {
    "langchain": False,
    "langgraph": False,
    "browser_use": False,
    "claude_agent_sdk": False,
    "google_adk": False,
    "strands": False,
    "llm": False,
    "tools": False,
    "dspy": False,
    "haystack": False,
    "pipecat": False,
}


def enable_all() -> None:
    """Enable all available auto-instrumentation."""
    enable_langchain()
    enable_langgraph()
    enable_browser_use()
    enable_claude_agent_sdk()
    enable_google_adk()
    enable_strands()
    enable_llm()
    enable_tools()
    enable_dspy()
    enable_haystack()
    enable_pipecat()


def enable_langchain() -> None:
    """Enable LangChain auto-instrumentation."""
    if _instrumentation_state["langchain"]:
        return

    try:
        from .langchain import patch_langchain

        patch_langchain()
        _instrumentation_state["langchain"] = True
    except ImportError:
        pass  # LangChain not installed


def enable_langgraph() -> None:
    """Enable LangGraph auto-instrumentation."""
    if _instrumentation_state["langgraph"]:
        return

    try:
        from .langgraph import patch_langgraph

        patch_langgraph()
        _instrumentation_state["langgraph"] = True
    except ImportError:
        pass  # LangGraph not installed


def enable_browser_use() -> None:
    """Enable Browser-Use auto-instrumentation."""
    if _instrumentation_state["browser_use"]:
        return

    try:
        from ..integrations.browser_use.auto_instrument import patch_browser_use

        patch_browser_use()
        _instrumentation_state["browser_use"] = True
    except ImportError:
        pass  # browser-use not installed


def enable_claude_agent_sdk() -> None:
    """Enable Claude Agent SDK auto-instrumentation."""
    if _instrumentation_state["claude_agent_sdk"]:
        return

    try:
        from ..integrations.claude_agent_sdk.auto_instrument import patch_claude_agent_sdk

        patch_claude_agent_sdk()
        _instrumentation_state["claude_agent_sdk"] = True
    except ImportError:
        pass  # claude-agent-sdk not installed


def enable_google_adk() -> None:
    """Enable Google ADK auto-instrumentation."""
    if _instrumentation_state["google_adk"]:
        return

    try:
        from ..integrations.google_adk.auto_instrument import patch_google_adk

        patch_google_adk()
        _instrumentation_state["google_adk"] = True
    except ImportError:
        pass  # google-adk not installed


def enable_strands() -> None:
    """Enable Strands Agents auto-instrumentation."""
    if _instrumentation_state["strands"]:
        return

    try:
        from ..integrations.strands.auto_instrument import patch_strands

        patch_strands()
        _instrumentation_state["strands"] = True
    except ImportError:
        pass  # strands-agents not installed


def enable_llm() -> None:
    """Enable LLM client auto-instrumentation."""
    if _instrumentation_state["llm"]:
        return

    try:
        from .llm import patch_all_llms

        patch_all_llms()
        _instrumentation_state["llm"] = True
    except ImportError:
        pass


def enable_tools() -> None:
    """Enable tool call auto-instrumentation."""
    if _instrumentation_state["tools"]:
        return

    try:
        from .tools import patch_tools

        patch_tools()
        _instrumentation_state["tools"] = True
    except ImportError:
        pass


def enable_dspy() -> None:
    """Enable DSPy auto-instrumentation."""
    if _instrumentation_state["dspy"]:
        return

    try:
        from .dspy import patch_dspy

        patch_dspy()
        _instrumentation_state["dspy"] = True
    except ImportError:
        pass  # DSPy not installed


def enable_haystack() -> None:
    """Enable Haystack auto-instrumentation."""
    if _instrumentation_state["haystack"]:
        return

    try:
        from .haystack import patch_haystack

        patch_haystack()
        _instrumentation_state["haystack"] = True
    except ImportError:
        pass  # Haystack not installed


def enable_pipecat() -> None:
    """Enable Pipecat auto-instrumentation."""
    if _instrumentation_state.get("pipecat"):
        return

    # Opt-in by default to avoid initializing Pipecat in non-voice apps.
    env_override = os.getenv("AIGIE_PIPECAT_AUTO_INSTRUMENT")
    if env_override is not None:
        should_enable = env_override.lower() in ("true", "1", "yes")
    else:
        env_enabled = os.getenv("AIGIE_PIPECAT_ENABLED")
        should_enable = env_enabled is not None and env_enabled.lower() in ("true", "1", "yes")

    if not should_enable:
        return

    try:
        from ..integrations.pipecat.auto_instrument import patch_pipecat

        patch_pipecat()
        _instrumentation_state["pipecat"] = True
    except ImportError:
        pass  # pipecat-ai not installed


def disable_all() -> None:
    """Disable all auto-instrumentation."""
    _instrumentation_state["langchain"] = False
    _instrumentation_state["langgraph"] = False
    _instrumentation_state["browser_use"] = False
    _instrumentation_state["claude_agent_sdk"] = False
    _instrumentation_state["google_adk"] = False
    _instrumentation_state["strands"] = False
    _instrumentation_state["llm"] = False
    _instrumentation_state["tools"] = False
    _instrumentation_state["dspy"] = False
    _instrumentation_state["haystack"] = False
    _instrumentation_state["pipecat"] = False


def is_enabled(framework: str) -> bool:
    """Check if instrumentation is enabled for a framework."""
    return _instrumentation_state.get(framework, False)
