package dev.lions.btpxpress.filter;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * Filtre de sécurité qui ajoute les headers HTTP de sécurité essentiels
 * pour protéger l'application contre diverses attaques.
 */
public class SecurityHeadersFilter implements Filter {

    private static final String STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security";
    private static final String X_FRAME_OPTIONS = "X-Frame-Options";
    private static final String X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
    private static final String X_XSS_PROTECTION = "X-XSS-Protection";
    private static final String REFERRER_POLICY = "Referrer-Policy";
    private static final String CONTENT_SECURITY_POLICY = "Content-Security-Policy";
    private static final String PERMISSIONS_POLICY = "Permissions-Policy";
    
    // HSTS - Force HTTPS pendant 1 an, inclut les sous-domaines
    private static final String HSTS_VALUE = "max-age=31536000; includeSubDomains; preload";
    
    // X-Frame-Options - Empêche le clickjacking
    private static final String X_FRAME_OPTIONS_VALUE = "DENY";
    
    // X-Content-Type-Options - Empêche le MIME sniffing
    private static final String X_CONTENT_TYPE_OPTIONS_VALUE = "nosniff";
    
    // X-XSS-Protection - Active la protection XSS du navigateur (legacy mais utile)
    private static final String X_XSS_PROTECTION_VALUE = "1; mode=block";
    
    // Referrer-Policy - Contrôle les informations de referrer envoyées
    private static final String REFERRER_POLICY_VALUE = "strict-origin-when-cross-origin";
    
    // Content Security Policy - Politique de sécurité stricte
    // Autorise uniquement les ressources depuis le même domaine et security.lions.dev
    private static final String CSP_VALUE = 
        "default-src 'self'; " +
        "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://security.lions.dev; " +
        "style-src 'self' 'unsafe-inline' https://security.lions.dev; " +
        "img-src 'self' data: https: blob:; " +
        "font-src 'self' data: https://security.lions.dev; " +
        "connect-src 'self' https://security.lions.dev https://api.btpxpress.lions.dev https://api.lions.dev; " +
        "frame-src 'self' https://security.lions.dev; " +
        "object-src 'none'; " +
        "base-uri 'self'; " +
        "form-action 'self' https://security.lions.dev; " +
        "frame-ancestors 'none'; " +
        "upgrade-insecure-requests;";
    
    // Permissions Policy - Désactive les fonctionnalités non nécessaires
    private static final String PERMISSIONS_POLICY_VALUE = 
        "geolocation=(), " +
        "microphone=(), " +
        "camera=(), " +
        "payment=(), " +
        "usb=(), " +
        "magnetometer=(), " +
        "gyroscope=(), " +
        "speaker=()";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // Initialisation non nécessaire
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // Ajouter les headers de sécurité uniquement pour les requêtes HTTPS
        if (httpRequest.isSecure() || 
            "https".equalsIgnoreCase(httpRequest.getHeader("X-Forwarded-Proto")) ||
            "https".equalsIgnoreCase(httpRequest.getHeader("X-Forwarded-Scheme"))) {
            
            // Strict Transport Security (HSTS)
            httpResponse.setHeader(STRICT_TRANSPORT_SECURITY, HSTS_VALUE);
            
            // Content Security Policy
            httpResponse.setHeader(CONTENT_SECURITY_POLICY, CSP_VALUE);
        }
        
        // Headers de sécurité applicables même en HTTP (développement)
        // Ces headers seront toujours présents
        httpResponse.setHeader(X_FRAME_OPTIONS, X_FRAME_OPTIONS_VALUE);
        httpResponse.setHeader(X_CONTENT_TYPE_OPTIONS, X_CONTENT_TYPE_OPTIONS_VALUE);
        httpResponse.setHeader(X_XSS_PROTECTION, X_XSS_PROTECTION_VALUE);
        httpResponse.setHeader(REFERRER_POLICY, REFERRER_POLICY_VALUE);
        httpResponse.setHeader(PERMISSIONS_POLICY, PERMISSIONS_POLICY_VALUE);
        
        // Headers supplémentaires pour renforcer la sécurité
        httpResponse.setHeader("X-Permitted-Cross-Domain-Policies", "none");
        httpResponse.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
        httpResponse.setHeader("Cross-Origin-Opener-Policy", "same-origin");
        httpResponse.setHeader("Cross-Origin-Resource-Policy", "same-origin");

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // Nettoyage non nécessaire
    }
}

