package dev.lions.security;

import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

/**
 * Filtre de sécurité pour ajouter des en-têtes HTTP de sécurité.
 * Ce filtre ajoute automatiquement les en-têtes de sécurité recommandés à toutes les réponses.
 *
 * @author Lions Dev Team
 * @version 1.0
 */
@Slf4j
@WebFilter("/*")
@ApplicationScoped
@RegisterForReflection
public class SecurityHeadersFilter implements jakarta.servlet.Filter {

  private static final String CSP_POLICY =
      "default-src 'self'; " +
      "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdnjs.cloudflare.com; " +
      "style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com; " +
      "img-src 'self' data: https:; " +
      "font-src 'self' https://cdnjs.cloudflare.com; " +
      "connect-src 'self'";

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    log.info("Initialisation du filtre des en-têtes de sécurité");
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {

    log.debug("Application des en-têtes de sécurité");

    HttpServletResponse httpResponse = (HttpServletResponse) response;

    // En-têtes de sécurité standards
    httpResponse.setHeader("X-Content-Type-Options", "nosniff");
    httpResponse.setHeader("X-Frame-Options", "SAMEORIGIN");
    httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
    httpResponse.setHeader("Content-Security-Policy", CSP_POLICY);
    httpResponse.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
    httpResponse.setHeader("Permissions-Policy", "geolocation=(), microphone=(), camera=()");

    // Ajout des en-têtes HSTS en production
    if ("production".equals(System.getProperty("quarkus.profile"))) {
      httpResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
    }

    chain.doFilter(request, response);
  }

  @Override
  public void destroy() {
    log.info("Destruction du filtre des en-têtes de sécurité");
  }
}