'use strict';

import type { Req, Res, Next } from '../types/http';

const crypto = require('crypto');

/** Generates a secure nonce for CSP policy. Call once per request. */
function getCspNonce(req: Req): string {
  if (!req.cspNonce) {
    req.cspNonce = crypto.randomBytes(16).toString('base64');
  }
  return req.cspNonce;
}

/**
 * Applies baseline security response headers on every request.
 * (See original notes on why CSP uses no nonce — index.html is static.)
 */
function securityHeaders(req: Req, res: Res, next: Next): void {
  const cspPolicy =
    `default-src 'self'; ` +
    `script-src 'self'; ` +
    `style-src 'self' 'unsafe-inline'; ` +
    `img-src 'self' data:; ` +
    `font-src 'self'; ` +
    `connect-src 'self'; ` +
    `frame-ancestors 'self'; ` +
    `form-action 'self'; ` +
    `base-uri 'self'; ` +
    `object-src 'none';`;

  res.setHeader('Content-Security-Policy', cspPolicy);
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-Frame-Options', 'SAMEORIGIN');
  res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
  res.setHeader('X-Permitted-Cross-Domain-Policies', 'none');
  res.removeHeader('X-Powered-By');

  // HSTS — only when explicitly configured to run over HTTPS.
  if (process.env.HTTPS === 'true') {
    res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  }

  next();
}

module.exports = { securityHeaders, getCspNonce };
