"""
OpenTelemetry instrumentation setup for REM agents.

Provides:
- OTLP exporter configuration
- Phoenix integration (OpenInference conventions)
- Resource attributes for agent metadata
- Idempotent setup (safe to call multiple times)
"""

from typing import Any

from loguru import logger

from ...settings import settings

# Global flag to track if instrumentation is initialized
_instrumentation_initialized = False


def setup_instrumentation() -> None:
    """
    Initialize OpenTelemetry instrumentation for REM agents.

    Idempotent - safe to call multiple times, only initializes once.

    Configures:
    - OTLP exporter (HTTP or gRPC)
    - Phoenix integration if enabled
    - Pydantic AI instrumentation (automatic via agent.instrument=True)
    - Resource attributes (service name, environment, etc.)

    Environment variables:
        OTEL__ENABLED - Enable instrumentation (default: false)
        OTEL__SERVICE_NAME - Service name (default: rem-api)
        OTEL__COLLECTOR_ENDPOINT - OTLP endpoint (default: http://localhost:4318)
        OTEL__PROTOCOL - Protocol (http or grpc, default: http)
        PHOENIX__ENABLED - Enable Phoenix (default: false)
        PHOENIX__COLLECTOR_ENDPOINT - Phoenix endpoint (default: http://localhost:6006/v1/traces)
    """
    global _instrumentation_initialized

    if _instrumentation_initialized:
        logger.debug("OTEL instrumentation already initialized, skipping")
        return

    if not settings.otel.enabled:
        logger.debug("OTEL instrumentation disabled (OTEL__ENABLED=false)")
        return

    logger.info("Initializing OpenTelemetry instrumentation...")

    try:
        from opentelemetry import trace
        from opentelemetry.sdk.trace import TracerProvider
        from opentelemetry.sdk.trace.export import BatchSpanProcessor
        from opentelemetry.sdk.resources import Resource, SERVICE_NAME, DEPLOYMENT_ENVIRONMENT
        from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPExporter
        from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as GRPCExporter

        # Create resource with service metadata
        resource = Resource(
            attributes={
                SERVICE_NAME: settings.otel.service_name,
                DEPLOYMENT_ENVIRONMENT: settings.environment,
                "service.team": settings.team,
            }
        )

        # Create tracer provider
        tracer_provider = TracerProvider(resource=resource)

        # Configure OTLP exporter based on protocol
        if settings.otel.protocol == "grpc":
            exporter = GRPCExporter(
                endpoint=settings.otel.collector_endpoint,
                timeout=settings.otel.export_timeout,
            )
        else:  # http
            exporter = HTTPExporter(
                endpoint=f"{settings.otel.collector_endpoint}/v1/traces",
                timeout=settings.otel.export_timeout,
            )

        # Add span processor
        tracer_provider.add_span_processor(BatchSpanProcessor(exporter))

        # Set as global tracer provider
        trace.set_tracer_provider(tracer_provider)

        logger.info(
            f"OTLP exporter configured: {settings.otel.collector_endpoint} ({settings.otel.protocol})"
        )

        # Add OpenInference span processor for Pydantic AI
        # This adds rich attributes (openinference.span.kind, input/output, etc.) to ALL traces
        # Phoenix receives these traces via the OTLP collector - no separate "Phoenix integration" needed
        try:
            from openinference.instrumentation.pydantic_ai import OpenInferenceSpanProcessor as PydanticAISpanProcessor

            tracer_provider.add_span_processor(PydanticAISpanProcessor())
            logger.info("Added OpenInference span processor for Pydantic AI")

        except ImportError:
            logger.warning(
                "openinference-instrumentation-pydantic-ai not installed - traces will lack OpenInference attributes. "
                "Install with: pip install openinference-instrumentation-pydantic-ai"
            )

        _instrumentation_initialized = True
        logger.info("OpenTelemetry instrumentation initialized successfully")

    except Exception as e:
        logger.error(f"Failed to initialize OTEL instrumentation: {e}")
        # Don't raise - allow application to continue without tracing


def set_agent_resource_attributes(agent_schema: dict[str, Any] | None = None) -> None:
    """
    Set resource attributes for agent execution.

    Called before creating agent to set span attributes with agent metadata.

    Args:
        agent_schema: Agent schema with metadata (kind, name, version, etc.)
    """
    if not settings.otel.enabled or not agent_schema:
        return

    try:
        from opentelemetry import trace

        # Get current span and set attributes
        span = trace.get_current_span()
        if span.is_recording():
            json_extra = agent_schema.get("json_schema_extra", {})
            kind = json_extra.get("kind")
            name = json_extra.get("name")
            version = json_extra.get("version", "unknown")

            if kind:
                span.set_attribute("agent.kind", kind)
            if name:
                span.set_attribute("agent.name", name)
            if version:
                span.set_attribute("agent.version", version)

            logger.debug(f"Set agent resource attributes: kind={kind}, name={name}, version={version}")

    except Exception as e:
        logger.warning(f"Failed to set agent resource attributes: {e}")
