"""
OpenTelemetry SDK bridge for Risicare.

Provides two integration modes:

1. **RisicareSpanExporter** — OTel SpanExporter that forwards spans to Risicare.
   Use when you have an existing OTel TracerProvider and want spans to also
   appear in Risicare.

2. **RisicareSpanProcessor** — OTel SpanProcessor for convenient TracerProvider
   integration. Wraps conversion and export in a single processor.

Usage (explicit):
    from opentelemetry.sdk.trace import TracerProvider
    from risicare.integrations.otel import RisicareSpanProcessor

    provider = TracerProvider()
    provider.add_span_processor(RisicareSpanProcessor())

Usage (automatic — requires otel_bridge=True):
    import risicare
    risicare.init(api_key="rsk-...", otel_bridge=True)
    import opentelemetry  # Auto-bridge activates
"""

from __future__ import annotations

import logging
import threading
from typing import Any

logger = logging.getLogger(__name__)

_instrumented = False
_lock = threading.Lock()


def instrument_opentelemetry(module: Any) -> None:
    """
    Auto-bridge OpenTelemetry when imported (if otel_bridge=True).

    Called by the import hook system when `opentelemetry` is imported.
    Only activates the bridge if the user has explicitly enabled it
    via otel_bridge=True to prevent double-counting spans.
    """
    global _instrumented
    if _instrumented:
        return

    with _lock:
        if _instrumented:
            return

        try:
            from risicare.client import get_client

            client = get_client()
            if client is None:
                # risicare.init() hasn't been called yet — don't mark as
                # instrumented so this hook can re-fire after init().
                logger.debug(
                    "OpenTelemetry detected but Risicare client not yet initialised. "
                    "Auto-bridge will retry after risicare.init()."
                )
                return

            if client.config.otel_bridge:
                from risicare.integrations.otel._bridge import inject_risicare_processor
                inject_risicare_processor()
                logger.debug("Auto-bridged OpenTelemetry → Risicare")
            else:
                logger.debug(
                    "OpenTelemetry detected but otel_bridge not enabled. "
                    "Set otel_bridge=True in risicare.init() to auto-bridge."
                )
        except Exception as e:
            # Don't mark as instrumented on failure — allow retry.
            logger.debug("Failed to auto-bridge OpenTelemetry: %s", e)
            return

        _instrumented = True


def __getattr__(name: str) -> Any:
    """Lazy re-export bridge classes to avoid import-time OTel dependency."""
    if name == "RisicareSpanExporter":
        from risicare.integrations.otel._bridge import RisicareSpanExporter
        return RisicareSpanExporter
    if name == "RisicareSpanProcessor":
        from risicare.integrations.otel._bridge import RisicareSpanProcessor
        return RisicareSpanProcessor
    if name == "convert_otel_to_risicare":
        from risicare.integrations.otel._converter import convert_otel_to_risicare
        return convert_otel_to_risicare
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
