//! Comprehensive Prometheus Metrics for API Gateway
//!
//! Provides detailed monitoring for:
//! - Authentication performance (6 layers)
//! - Backend proxy latencies
//! - Configuration hot-reload events
//! - Rate limiting effectiveness
//! - Circuit breaker states
//!
//! ## Metric Categories
//!
//! 1. **Auth Metrics**: JWT validation, revocation checks, RBAC, MFA
//! 2. **Proxy Metrics**: Backend latencies, connection pool, circuit breaker
//! 3. **Config Metrics**: NOTIFY events, cache hits/misses, hot-reload latency
//! 4. **Exporter**: Prometheus /metrics endpoint

pub mod auth_metrics;
pub mod config_metrics;
pub mod exporter;
pub mod proxy_metrics;

// Re-export core types
pub use auth_metrics::AuthMetrics;
pub use config_metrics::ConfigMetrics;
pub use exporter::{combined_router, metrics_router, PrometheusExporter};
pub use proxy_metrics::ProxyMetrics;

use prometheus::Registry;
use std::sync::Arc;

/// Central metrics registry for API Gateway
#[derive(Clone)]
pub struct GatewayMetrics {
    pub auth: Arc<AuthMetrics>,
    pub proxy: Arc<ProxyMetrics>,
    pub config: Arc<ConfigMetrics>,
    pub registry: Arc<Registry>,
}

impl GatewayMetrics {
    /// Create new metrics registry with all subsystems
    pub fn new() -> Result<Self, prometheus::Error> {
        let registry = Arc::new(Registry::new());

        let auth = Arc::new(AuthMetrics::new(&registry)?);
        let proxy = Arc::new(ProxyMetrics::new(&registry)?);
        let config = Arc::new(ConfigMetrics::new(&registry)?);

        Ok(Self {
            auth,
            proxy,
            config,
            registry,
        })
    }

    /// Get reference to Prometheus registry for exporter
    pub fn registry(&self) -> Arc<Registry> {
        self.registry.clone()
    }
}

impl Default for GatewayMetrics {
    fn default() -> Self {
        match Self::new() {
            Ok(metrics) => metrics,
            Err(_) => {
                // Metrics initialization should not fail in practice;
                // abort rather than panicking to satisfy deny(expect_used).
                std::process::abort();
            }
        }
    }
}
