"""Framework → OpenInference instrumentor mapping."""
from __future__ import annotations

from dataclasses import dataclass
from typing import Callable


@dataclass(frozen=True)
class Entry:
    name: str
    instrumentor_factories: tuple[Callable[[], object], ...]


def _langchain_instrumentor() -> object:
    from openinference.instrumentation.langchain import LangChainInstrumentor
    instrumentor = LangChainInstrumentor()
    # Patch missing callback methods that newer LangChain versions call.
    # openinference-instrumentation-langchain may not have implemented these yet.
    _tracer_cls = None
    try:
        from openinference.instrumentation.langchain._tracer import OpenInferenceTracer
        _tracer_cls = OpenInferenceTracer
    except ImportError:
        pass
    if _tracer_cls is not None:
        for method in ("on_resume", "on_interrupt"):
            if not hasattr(_tracer_cls, method):
                setattr(_tracer_cls, method, lambda self, *a, **kw: None)
    return instrumentor


def _crewai_instrumentor() -> object:
    from openinference.instrumentation.crewai import CrewAIInstrumentor
    return CrewAIInstrumentor()


def _litellm_instrumentor() -> object:
    from openinference.instrumentation.litellm import LiteLLMInstrumentor
    return LiteLLMInstrumentor()


def _llama_index_instrumentor() -> object:
    from openinference.instrumentation.llama_index import LlamaIndexInstrumentor
    return LlamaIndexInstrumentor()


def _openai_instrumentor() -> object:
    from openinference.instrumentation.openai import OpenAIInstrumentor
    return OpenAIInstrumentor()


def _openai_agents_instrumentor() -> object:
    from openinference.instrumentation.openai_agents import OpenAIAgentsInstrumentor
    return OpenAIAgentsInstrumentor()


def _anthropic_instrumentor() -> object:
    from openinference.instrumentation.anthropic import AnthropicInstrumentor
    return AnthropicInstrumentor()


def _beeai_instrumentor() -> object:
    from openinference.instrumentation.beeai import BeeAIInstrumentor
    return BeeAIInstrumentor()


def _agno_instrumentor() -> object:
    from openinference.instrumentation.agno import AgnoInstrumentor
    return AgnoInstrumentor()


def _autogen_agentchat_instrumentor() -> object:
    from openinference.instrumentation.autogen_agentchat import AutoGenAgentChatInstrumentor
    return AutoGenAgentChatInstrumentor()


def _autogen_instrumentor() -> object:
    from openinference.instrumentation.autogen import AutoGenInstrumentor
    return AutoGenInstrumentor()


def _bedrock_instrumentor() -> object:
    from openinference.instrumentation.bedrock import BedrockInstrumentor
    return BedrockInstrumentor()


def _claude_agent_sdk_instrumentor() -> object:
    from openinference.instrumentation.claude_agent_sdk import ClaudeAgentSDKInstrumentor
    return ClaudeAgentSDKInstrumentor()


def _dspy_instrumentor() -> object:
    from openinference.instrumentation.dspy import DSPyInstrumentor
    return DSPyInstrumentor()


def _google_adk_instrumentor() -> object:
    from openinference.instrumentation.google_adk import GoogleADKInstrumentor
    return GoogleADKInstrumentor()


def _google_genai_instrumentor() -> object:
    from openinference.instrumentation.google_genai import GoogleGenAIInstrumentor
    return GoogleGenAIInstrumentor()


def _groq_instrumentor() -> object:
    from openinference.instrumentation.groq import GroqInstrumentor
    return GroqInstrumentor()


def _guardrails_instrumentor() -> object:
    from openinference.instrumentation.guardrails import GuardrailsInstrumentor
    return GuardrailsInstrumentor()


def _mistralai_instrumentor() -> object:
    from openinference.instrumentation.mistralai import MistralAIInstrumentor
    return MistralAIInstrumentor()


REGISTRY: tuple[Entry, ...] = (
    Entry(name="langchain", instrumentor_factories=(_langchain_instrumentor,)),
    Entry(name="crewai", instrumentor_factories=(_crewai_instrumentor, _litellm_instrumentor)),
    Entry(name="llama-index", instrumentor_factories=(_llama_index_instrumentor,)),
    Entry(name="openai", instrumentor_factories=(_openai_instrumentor,)),
    Entry(name="openai-agents", instrumentor_factories=(_openai_agents_instrumentor,)),
    Entry(name="anthropic", instrumentor_factories=(_anthropic_instrumentor,)),
    Entry(name="beeai", instrumentor_factories=(_beeai_instrumentor,)),
    Entry(name="agno", instrumentor_factories=(_agno_instrumentor,)),
    Entry(name="autogen-agentchat", instrumentor_factories=(_autogen_agentchat_instrumentor,)),
    Entry(name="autogen", instrumentor_factories=(_autogen_instrumentor,)),
    Entry(name="bedrock", instrumentor_factories=(_bedrock_instrumentor,)),
    Entry(name="claude-agent-sdk", instrumentor_factories=(_claude_agent_sdk_instrumentor,)),
    Entry(name="dspy", instrumentor_factories=(_dspy_instrumentor,)),
    Entry(name="google-adk", instrumentor_factories=(_google_adk_instrumentor,)),
    Entry(name="google-genai", instrumentor_factories=(_google_genai_instrumentor,)),
    Entry(name="groq", instrumentor_factories=(_groq_instrumentor,)),
    Entry(name="guardrails", instrumentor_factories=(_guardrails_instrumentor,)),
    Entry(name="mistralai", instrumentor_factories=(_mistralai_instrumentor,)),
)
