import { createMiddleware } from "hono/factory";
import { config } from "./config.js";

/**
 * Content-Security-Policy value for the SPA.
 *
 * - `style-src 'unsafe-inline'` is required because Tailwind injects inline styles.
 * - `connect-src ws: wss:` allows WebSocket connections to the CLI bridge.
 * - `img-src data: blob:` permits data-URI and blob images used by the UI.
 * - `frame-ancestors 'none'` supersedes X-Frame-Options for modern browsers.
 */
const CONTENT_SECURITY_POLICY = [
  "default-src 'self'",
  "script-src 'self'",
  "style-src 'self' 'unsafe-inline'",
  "img-src 'self' data: blob:",
  "connect-src 'self' ws: wss:",
  "font-src 'self'",
  "object-src 'none'",
  "base-uri 'self'",
  "form-action 'self'",
  "frame-ancestors 'none'",
].join("; ");

/**
 * Permissions-Policy value — disable browser features the app does not use.
 */
const PERMISSIONS_POLICY = "camera=(), microphone=(), geolocation=(), payment=()";

/**
 * Security headers middleware.
 *
 * Sets defensive HTTP headers on every response to mitigate:
 * - MIME-type sniffing (X-Content-Type-Options)
 * - Clickjacking (X-Frame-Options + CSP frame-ancestors)
 * - Referrer leakage (Referrer-Policy)
 * - Legacy XSS filter issues (X-XSS-Protection)
 * - Script/resource injection (Content-Security-Policy)
 * - Unused browser feature access (Permissions-Policy)
 * - Downgrade attacks (Strict-Transport-Security, opt-in via ZENCODE_TRUST_PROXY)
 */
export function securityHeaders() {
  return createMiddleware(async (c, next) => {
    await next();

    c.header("X-Content-Type-Options", "nosniff");
    c.header("X-Frame-Options", "DENY");
    c.header("Referrer-Policy", "strict-origin-when-cross-origin");
    c.header("X-XSS-Protection", "0");
    c.header("Content-Security-Policy", CONTENT_SECURITY_POLICY);
    c.header("Permissions-Policy", PERMISSIONS_POLICY);

    if (config.trustProxy) {
      c.header(
        "Strict-Transport-Security",
        "max-age=31536000; includeSubDomains",
      );
    }
  });
}
