/**
 * Hook utilities for @beignet/core/server
 */

import type { AnyPorts } from "../../ports/index.js";
import type { ServerHook } from "../http.js";

export {
  type AuthHookArgs,
  type AuthHooksOptions,
  type AuthRouteHooks,
  createAuthHooks,
} from "./auth.js";
export {
  applyCorsHeaders,
  type CorsConfig,
  createCorsHooks,
} from "./cors.js";
export {
  createErrorReportingHooks,
  type ErrorReporterResolver,
  type ErrorReportingContext,
  type ErrorReportingHookArgs,
  type ErrorReportingHooksOptions,
  shouldReportServerError,
} from "./error-reporting.js";
export {
  defaultMapErrorToResponse,
  type ErrorMappingConfig,
  type ErrorMappingResult,
} from "./errors.js";
export {
  type CtxWithIdempotency,
  createIdempotencyHooks,
  type IdempotencyHooksOptions,
  type IdempotencyPorts,
} from "./idempotency.js";
export {
  createLoggingHooks,
  type Logger,
  type LoggingConfig,
} from "./logging.js";
export {
  type CtxWithRateLimit,
  createRateLimitHooks,
  type RateLimitIpSource,
  type RateLimitOptions,
} from "./rate-limit.js";
export {
  applySecurityHeaders,
  type CsrfFailureReason,
  type CsrfHooksOptions,
  type CsrfTokenOptions,
  createCsrfHooks,
  createSecurityHeadersHooks,
  type SecurityHeadersOptions,
  type StrictTransportSecurityOptions,
} from "./security.js";

/**
 * Flatten hook arrays into a single hook list.
 */
export function composeHooks<Ctx, Ports extends AnyPorts = AnyPorts>(
  ...hooks: (ServerHook<Ctx, Ports> | readonly ServerHook<Ctx, Ports>[])[]
): ServerHook<Ctx, Ports>[] {
  return hooks.flatMap((hook) => (Array.isArray(hook) ? hook : [hook]));
}
