/**
 * OpenAPI generation handler
 * OpenAPI helpers for the Beignet server runtime.
 */

import type { HttpContractConfig } from "../contracts/index.js";
import type { AppEnvironment } from "./health.js";
import type { HttpRequestLike, HttpResponseLike } from "./types.js";

/**
 * OpenAPI route handler configuration.
 */
export interface OpenAPIConfig {
  /** Enable OpenAPI endpoint (default: false) */
  enabled?: boolean;
  /**
   * Suggested path for the OpenAPI endpoint (e.g., "/api/openapi.json").
   * NOTE: This field is for documentation/metadata only and does not control routing.
   * You must manually wire the openapiHandler to your desired route.
   */
  suggestedPath?: string;
  /** API title */
  title?: string;
  /** API version */
  version?: string;
  /** API description */
  description?: string;
}

/**
 * Create a framework-neutral OpenAPI JSON handler.
 *
 * The OpenAPI document is generated lazily on the first request and then cached
 * for the lifetime of the handler.
 */
export function createOpenAPIHandler(
  contracts: readonly HttpContractConfig[],
  openapiConfig: OpenAPIConfig | undefined,
  _env: AppEnvironment,
): (req: HttpRequestLike) => Promise<HttpResponseLike> {
  // Lazily generate OpenAPI spec on first request
  let cachedSpec: object | null = null;

  return async (_req: HttpRequestLike): Promise<HttpResponseLike> => {
    // Generate spec if not cached
    if (!cachedSpec) {
      try {
        // Dynamic import to avoid hard dependency
        const { contractsToOpenAPI } = await import("../openapi/index.js");
        cachedSpec = contractsToOpenAPI(contracts, {
          title: openapiConfig?.title ?? "Beignet API",
          version: openapiConfig?.version ?? "1.0.0",
          description: openapiConfig?.description,
        });
      } catch (error) {
        // OpenAPI generation failed
        return {
          status: 500,
          body: {
            error: "OpenAPI generation failed",
            message: error instanceof Error ? error.message : "Unknown error",
          },
          headers: { "Content-Type": "application/json" },
        };
      }
    }

    return {
      status: 200,
      body: cachedSpec,
      headers: { "Content-Type": "application/json" },
    };
  };
}
