"""Telemetry setup and shutdown.

This module provides backward-compatible setup/shutdown APIs.
The primary init path is now init_supervision() in entry.py, which calls
t_obs.configure_observability() directly.
"""

import logging
from types import TracebackType
from typing import Any, Dict, Optional, Type

from t_obs import configure_observability, is_configured, ObsConfig

from thoughtful.supervisor.telemetry.config import (
    TelemetryConfig,
    TelemetryConfigBuilder,
    TelemetryContext,
    get_global_telemetry_context,
    set_global_telemetry_context,
    set_service_name,
    clear_global_telemetry_context,
)
from thoughtful.supervisor.telemetry.resources import extract_resource_attributes

logger = logging.getLogger(__name__)


def setup_telemetry_from_config(config: TelemetryConfig) -> TelemetryContext:
    """Initialize telemetry using t_obs.

    .. deprecated::
        This function exists for backward compatibility and will be removed
        in a future release. Use ``init_supervision()`` from
        ``thoughtful.supervisor.entry`` instead, which configures t_obs
        directly without the TelemetryConfig indirection.
    """
    import warnings

    from thoughtful.supervisor.telemetry.traces.spans import create_root_span

    warnings.warn(
        "setup_telemetry_from_config() is deprecated and will be removed. "
        "Use init_supervision() instead.",
        DeprecationWarning,
        stacklevel=2,
    )

    context = TelemetryContext(config=config)

    # Set global service name for get_tracer/get_meter/get_logger
    set_service_name(config.service_name)

    # Build resource attributes
    resource_attrs = extract_resource_attributes()

    if config.resource_attributes:
        resource_attrs.update(config.resource_attributes)

    # Configure via t_obs — only set service name and resource attributes
    try:
        configure_observability(
            service_name=config.service_name,
            config=ObsConfig(
                service_name=config.service_name,
                resource_attributes=resource_attrs,
            ),
        )
        logger.debug("t_obs observability configured")
    except Exception as e:
        logger.error("Failed to configure t_obs: %s", e)

    # Create root span (supervisor-specific lifecycle)
    if config.enable_tracing:
        try:
            context.root_span_cm, context.root_span = create_root_span(
                config.service_name
            )
            logger.debug("Created root span for %s", config.service_name)
        except Exception as e:
            logger.error("Failed to create root span: %s", e)

    set_global_telemetry_context(context)
    logger.info("Telemetry initialization completed")
    return context


def shutdown_telemetry_from_context(
    context: TelemetryContext,
    exc_type: Optional[Type[Exception]] = None,
    exc_val: Optional[Exception] = None,
    exc_tb: Optional[TracebackType] = None,
    workflow_data: Optional[Dict[str, Any]] = None,
) -> None:
    """Shutdown telemetry components and record workflow completion."""
    from opentelemetry import metrics, trace
    from opentelemetry._logs import get_logger_provider

    from thoughtful.supervisor.telemetry.traces import close_root_span
    from thoughtful.supervisor.telemetry.traces.step_tracer import StepTracer

    # Close root span
    if context.root_span_cm is not None and context.root_span is not None:
        close_root_span(
            context.root_span_cm,
            context.root_span,
            exc_type,
            exc_val,
            exc_tb,
            workflow_data,
        )

    # Flush all providers to ensure telemetry data is exported
    try:
        tracer_provider = trace.get_tracer_provider()
        if hasattr(tracer_provider, "force_flush"):
            tracer_provider.force_flush(timeout_millis=5000)
    except Exception as e:
        logger.debug("Error flushing tracer provider: %s", e)

    try:
        meter_provider = metrics.get_meter_provider()
        if hasattr(meter_provider, "force_flush"):
            meter_provider.force_flush(timeout_millis=5000)
    except Exception as e:
        logger.debug("Error flushing meter provider: %s", e)

    try:
        logger_provider = get_logger_provider()
        if hasattr(logger_provider, "force_flush"):
            logger_provider.force_flush(timeout_millis=5000)
    except Exception as e:
        logger.debug("Error flushing logger provider: %s", e)

    # Reset step tracer class-level state
    StepTracer.reset()

    # Clear global context
    clear_global_telemetry_context()


def setup_telemetry(
    otlp_config: Optional[Dict[str, Any]] = None,
    manifest: Any = None,
    service_name: str = "supervisor",
) -> TelemetryContext:
    """Initialize all telemetry components using t_obs.

    .. deprecated::
        This function exists for backward compatibility and will be removed
        in a future release. Use ``init_supervision()`` from
        ``thoughtful.supervisor.entry`` instead.
    """
    import warnings

    warnings.warn(
        "setup_telemetry() is deprecated and will be removed. "
        "Use init_supervision() instead.",
        DeprecationWarning,
        stacklevel=2,
    )
    if otlp_config is not None:
        warnings.warn(
            "otlp_config is deprecated and ignored. "
            "OTLP endpoint is configured via OTEL_EXPORTER_OTLP_ENDPOINT env var or ObsConfig defaults.",
            DeprecationWarning,
            stacklevel=2,
        )
    config = (
        TelemetryConfigBuilder()
        .with_service_name(service_name)
        .with_manifest(manifest)
        .with_otlp_config(otlp_config)
        .build()
    )

    return setup_telemetry_from_config(config)


def shutdown_telemetry(
    context: TelemetryContext,
    exc_type: Optional[Type[Exception]] = None,
    exc_val: Optional[Exception] = None,
    exc_tb: Optional[TracebackType] = None,
    workflow_data: Optional[Dict[str, Any]] = None,
) -> None:
    """Shutdown telemetry components and record workflow completion."""
    shutdown_telemetry_from_context(context, exc_type, exc_val, exc_tb, workflow_data)


# Convenience functions for accessing telemetry state
def get_current_root_span():
    """Get the current root span from the global telemetry context."""
    context = get_global_telemetry_context()
    return context.root_span if context else None


def is_telemetry_initialized() -> bool:
    """Check if telemetry is currently initialized."""
    return is_configured()


def get_telemetry_config() -> Optional[TelemetryConfig]:
    """Get the current telemetry configuration."""
    context = get_global_telemetry_context()
    return context.config if context else None
