"""
CrewAI integration for Risicare SDK.

Patches Crew.kickoff (root trace), agent execution (agent spans),
and task execution (task spans). Does NOT suppress provider
instrumentation — lets OpenAI/Anthropic provider patches create
LLM spans naturally as children of CrewAI agent spans.

Span Hierarchy:
    crewai.crew/{crew_name}            [AGENT, role=ORCHESTRATOR]
      crewai.task/{description}         [INTERNAL, phase=ACT]
        crewai.agent/{agent_role}        [AGENT, role=WORKER]
          openai.chat.completions.create  [LLM_CALL — from provider]
          crewai.tool/{tool_name}         [TOOL_CALL, phase=ACT]
        crewai.delegation/{from}→{to}     [DELEGATION, phase=COORDINATE]

Usage (automatic — zero config):
    import risicare
    risicare.init(api_key="rsk-...")
    crew = Crew(agents=[...], tasks=[...])
    crew.kickoff()  # Automatically traced
"""

from __future__ import annotations

import logging
import threading
from typing import Any

logger = logging.getLogger(__name__)

_instrumented = False
_lock = threading.RLock()


def instrument_crewai(module: Any) -> None:
    """
    Apply instrumentation to CrewAI module.

    Called by the import hook system when `crewai` is imported.
    """
    global _instrumented
    if _instrumented:
        return

    with _lock:
        if _instrumented:
            return
        _instrumented = True
        try:
            from risicare.integrations._base import check_version_compatibility

            check_version_compatibility("crewai")

            from risicare.integrations.crewai._patches import patch_crewai

            patch_crewai(module)
            logger.debug("Instrumented CrewAI")
        except Exception as e:
            _instrumented = False
            logger.debug(f"Failed to instrument CrewAI: {e}")
