//! Security headers middleware
//!
//! SEC-7: XSS Prevention via Content-Security-Policy
//! SEC-12: Additional security headers

use axum::{extract::Request, middleware::Next, response::Response};

/// Add security headers to all responses
pub async fn add_security_headers(request: Request, next: Next) -> Response {
    // Capture the path before the request is consumed downstream, so we can pick
    // the right Cache-Control for the SPA: hashed assets are immutable and can be
    // cached forever; everything else (index.html for `/`, deep links, and API
    // JSON) must revalidate so a fresh deploy is picked up immediately.
    let path = request.uri().path().to_owned();

    let mut response = next.run(request).await;
    let headers = response.headers_mut();

    // Cache-Control. Vite emits content-hashed filenames under `/assets/`, so
    // those are safe to cache aggressively (`immutable`); a new build changes the
    // hash and therefore the URL. The SPA shell (index.html), served for `/` and
    // every BrowserRouter deep link, must NOT be cached stale or clients would
    // load an old shell pointing at assets that no longer exist after a deploy —
    // hence `no-cache, must-revalidate`. Only set this when a downstream handler
    // hasn't already chosen its own caching policy.
    if !headers.contains_key(axum::http::header::CACHE_CONTROL) {
        let cache_value = if path.starts_with("/assets/") {
            "public, max-age=31536000, immutable"
        } else {
            "no-cache, must-revalidate"
        };
        if let Ok(v) = cache_value.parse() {
            headers.insert(axum::http::header::CACHE_CONTROL, v);
        }
    }

    // SEC-7: Content Security Policy (XSS Prevention)
    // This CSP allows inline scripts/styles (needed for dashboard) but blocks external resources
    headers.insert(
        "Content-Security-Policy",
        "default-src 'self'; \
         script-src 'self' 'unsafe-inline'; \
         style-src 'self' 'unsafe-inline'; \
         img-src 'self' data:; \
         font-src 'self'; \
         connect-src 'self' ws: wss:; \
         frame-ancestors 'none'; \
         base-uri 'self'; \
         form-action 'self'"
            .parse()
            .unwrap(),
    );

    // SEC-12: X-Frame-Options (Clickjacking protection)
    headers.insert("X-Frame-Options", "DENY".parse().unwrap());

    // SEC-12: X-Content-Type-Options (MIME sniffing protection)
    headers.insert("X-Content-Type-Options", "nosniff".parse().unwrap());

    // SEC-12: X-XSS-Protection (Legacy XSS filter - deprecated but still useful)
    headers.insert("X-XSS-Protection", "1; mode=block".parse().unwrap());

    // SEC-12: Referrer-Policy (Control referrer information)
    headers.insert(
        "Referrer-Policy",
        "strict-origin-when-cross-origin".parse().unwrap(),
    );

    // SEC-12: Permissions-Policy (Feature policy)
    headers.insert(
        "Permissions-Policy",
        "geolocation=(), microphone=(), camera=()".parse().unwrap(),
    );

    // SEC-10: Strict-Transport-Security (HSTS - only when using HTTPS)
    // Uncomment when HTTPS is enabled:
    // headers.insert(
    //     "Strict-Transport-Security",
    //     "max-age=31536000; includeSubDomains; preload".parse().unwrap(),
    // );

    response
}
