/**
 * Utility functions for server configuration.
 * Exported separately to allow testing without triggering server start.
 */

import { existsSync, mkdirSync } from "fs";
import { resolve } from "path";
import type { CookieSerializeOptions } from "@fastify/cookie";

/**
 * Parse comma-separated CORS origins string
 */
export function parseCorsOrigins(originsStr: string): string[] {
  return originsStr
    .split(",")
    .map((o) => o.trim())
    .filter((o) => o.length > 0);
}

/**
 * Build base cookie options for access token
 */
export function buildBaseCookieOptions(
  accessTtlMinutes: number,
  isProduction: boolean
): CookieSerializeOptions {
  return {
    httpOnly: true,
    secure: isProduction,
    sameSite: "lax",
    path: "/",
    maxAge: accessTtlMinutes * 60, // Convert minutes to seconds
  };
}

/**
 * Build refresh cookie options (extends base with longer TTL)
 */
export function buildRefreshCookieOptions(
  baseCookieOptions: CookieSerializeOptions,
  refreshTtlDays: number
): CookieSerializeOptions {
  return {
    ...baseCookieOptions,
    maxAge: refreshTtlDays * 24 * 60 * 60, // Convert days to seconds
  };
}

/**
 * Build complete app configuration object
 */
export interface AppConfigOptions {
  jwtSecret?: string;
  refreshSecret?: string;
  accessTtlMinutes: number;
  refreshTtlDays: number;
  isProduction: boolean;
}

export interface AppConfig {
  accessSecret: string;
  refreshSecret: string;
  accessTtl: number;
  refreshTtl: number;
  cookieOptions: CookieSerializeOptions;
  refreshCookieOptions: CookieSerializeOptions;
}

export function buildAppConfig(options: AppConfigOptions): AppConfig {
  const cookieOptions = buildBaseCookieOptions(
    options.accessTtlMinutes,
    options.isProduction
  );
  const refreshCookieOptions = buildRefreshCookieOptions(
    cookieOptions,
    options.refreshTtlDays
  );

  return {
    accessSecret: options.jwtSecret || "",
    refreshSecret: options.refreshSecret || "",
    accessTtl: options.accessTtlMinutes,
    refreshTtl: options.refreshTtlDays,
    cookieOptions,
    refreshCookieOptions,
  };
}

/**
 * Ensure images directory exists
 */
export function ensureImagesDirectory(cwd?: string): string {
  const basePath = cwd || process.cwd();
  const imagesDir = resolve(basePath, "data/images");
  if (!existsSync(imagesDir)) {
    mkdirSync(imagesDir, { recursive: true });
  }
  return imagesDir;
}

/**
 * Get JWT configuration based on auth enabled status
 */
export interface JwtConfig {
  secret: string;
  cookie: {
    cookieName: string;
    signed: boolean;
  };
}

export function getJwtConfig(authEnabled: boolean, jwtSecret?: string): JwtConfig {
  const effectiveSecret =
    authEnabled && jwtSecret
      ? jwtSecret
      : "auth-disabled-no-secret-needed";

  return {
    secret: effectiveSecret,
    cookie: {
      cookieName: "access_token",
      signed: false,
    },
  };
}
