use axum::http::header::CONTENT_SECURITY_POLICY;
use axum::http::{Request, StatusCode};
use axum::middleware::{from_fn, Next};
use axum::Router;
use headers::{AccessControlMaxAge, HeaderMapExt};
use hyper::Response;
use std::time::Duration;
use tower::util::MapResponseLayer;
use tower_http::services::{ServeDir, ServeFile};

pub fn static_serve_sw(file: &str) -> Router {
    Router::new()
        .nest_service("", ServeFile::new(file))
        .layer(MapResponseLayer::new(|mut res: Response<_>| {
            res.headers_mut()
                .typed_insert(AccessControlMaxAge::from(Duration::from_secs(60 * 10)));

            res
        }))
}

pub fn static_serve(dir: &str) -> Router {
    let serve_dir = ServeDir::new(dir);
    Router::new()
        .nest_service("", serve_dir)
        .layer(MapResponseLayer::new(|mut res: Response<_>| {
            res.headers_mut()
                .typed_insert(AccessControlMaxAge::from(Duration::from_secs(
                    60 * 60 * 24 * 7,
                )));

            res
        }))
}

pub fn static_serve_svg(dir: &str) -> Router {
    let serve_dir = ServeDir::new(dir);
    Router::new()
        .nest_service("", serve_dir)
        .layer(from_fn(|req: Request<_>, next: Next| async {
            if !req.uri().path().ends_with(".svg") {
                return Err(StatusCode::NOT_FOUND);
            }

            Ok(next.run(req).await)
        }))
        .layer(MapResponseLayer::new(|mut res: Response<_>| {
            let headers = res.headers_mut();
            headers.typed_insert(AccessControlMaxAge::from(Duration::from_secs(
                60 * 60 * 24 * 7,
            )));
            headers.insert(
                CONTENT_SECURITY_POLICY,
                "default-src 'none'; style-src 'unsafe-inline'"
                    .parse()
                    .unwrap(),
            );

            res
        }))
}
