use axum::Router;

use crate::rest::{RestConfig, middleware::apply_default_layers};

/// Tower-first REST layer stack builder.
///
/// The current implementation preserves the existing rs-zero REST middleware
/// order while exposing an explicit stack object. Future releases can move
/// individual middleware pieces behind concrete Tower [`tower::Layer`] types
/// without changing [`RestServer`](crate::rest::RestServer) callers.
#[derive(Debug, Clone)]
pub struct RestLayerStack {
    config: RestConfig,
}

impl RestLayerStack {
    /// Creates a REST layer stack from runtime configuration.
    pub fn new(config: RestConfig) -> Self {
        Self { config }
    }

    /// Creates a production-oriented REST layer stack.
    pub fn go_zero_defaults(name: impl Into<String>) -> Self {
        Self::new(RestConfig::go_zero_defaults(name))
    }

    /// Applies the stack to an axum router.
    pub fn layer(&self, router: Router) -> Router {
        apply_default_layers(router, self.config.clone())
    }

    /// Returns an axum-compatible layer value.
    pub fn into_layer(self) -> RestRouterLayer {
        RestRouterLayer {
            config: self.config,
        }
    }
}

/// Axum router layer produced by [`RestLayerStack`].
#[derive(Debug, Clone)]
pub struct RestRouterLayer {
    config: RestConfig,
}

impl tower::Layer<Router> for RestRouterLayer {
    type Service = Router;

    fn layer(&self, inner: Router) -> Self::Service {
        apply_default_layers(inner, self.config.clone())
    }
}
