/**
 * JSON Schema for `prisma.compute.json`, built from the same constants as the
 * runtime validator so enums and key sets cannot drift.
 *
 * The schema exists for editor assistance ($schema autocomplete/validation)
 * and static tooling. It encodes structure, enums, and ranges; cross-field
 * rules (e.g. the custom framework requiring build output settings) stay in
 * `normalizeComputeConfig`, which remains the authority for every format.
 */

import { COMPUTE_FRAMEWORKS, COMPUTE_REGIONS } from "./types.ts";

/**
 * Intended publish location of the compute config JSON Schema. The URL does
 * not resolve yet, so serializers omit `$schema` by default; once the schema
 * is hosted here, pass this constant to `serializeComputeConfigJson` to emit
 * it in generated configs.
 */
export const COMPUTE_CONFIG_JSON_SCHEMA_URL =
  "https://schemas.prisma.io/compute.schema.json";

const ENV_SCHEMA = {
  description:
    "Environment variables for the deploy. A string is shorthand for a dotenv file path.",
  oneOf: [
    { type: "string", minLength: 1 },
    {
      type: "object",
      additionalProperties: false,
      properties: {
        file: {
          description:
            "Dotenv file path(s) resolved relative to the config file directory.",
          oneOf: [
            { type: "string", minLength: 1 },
            { type: "array", items: { type: "string", minLength: 1 } },
          ],
        },
        vars: {
          description:
            "Inline environment variable assignments. This file is committed — keep secrets in platform branch config.",
          type: "object",
          additionalProperties: { type: "string", minLength: 1 },
        },
      },
    },
  ],
} as const;

const BUILD_SCHEMA = {
  description:
    "Build settings. When present, these own the app's build configuration.",
  type: "object",
  additionalProperties: false,
  properties: {
    command: {
      description:
        "Build command run in the app root. null skips the build step.",
      type: ["string", "null"],
    },
    outputDirectory: {
      description:
        'Framework output path relative to the app root, e.g. ".next/standalone".',
      type: "string",
      minLength: 1,
    },
    entrypoint: {
      description:
        "Entrypoint for the built artifact, relative to outputDirectory when one is set.",
      type: "string",
      minLength: 1,
    },
  },
} as const;

const APP_SCHEMA = {
  type: "object",
  additionalProperties: false,
  properties: {
    name: {
      description: "Deployed app name. Defaults to inference.",
      type: "string",
      minLength: 1,
    },
    region: {
      description: "App region override. Defaults to the project region.",
      enum: COMPUTE_REGIONS,
    },
    root: {
      description:
        "App directory relative to the config file. Defaults to the config file directory.",
      type: "string",
      minLength: 1,
    },
    framework: {
      description:
        "Framework to deploy. Defaults to detection from the app directory.",
      enum: COMPUTE_FRAMEWORKS,
    },
    entry: {
      description:
        "Entrypoint path for Bun (and Hono) deploys, relative to the app root.",
      type: "string",
      minLength: 1,
    },
    httpPort: {
      description:
        "HTTP port the deployed app listens on. Defaults to the framework default.",
      type: "integer",
      minimum: 1,
      maximum: 65535,
    },
    env: ENV_SCHEMA,
    build: BUILD_SCHEMA,
  },
} as const;

/**
 * The compute config JSON Schema document (draft-07 for the broadest editor
 * support). Publish this at `COMPUTE_CONFIG_JSON_SCHEMA_URL`.
 */
export const COMPUTE_CONFIG_JSON_SCHEMA = {
  $schema: "http://json-schema.org/draft-07/schema#",
  $id: COMPUTE_CONFIG_JSON_SCHEMA_URL,
  title: "Prisma Compute config",
  description:
    "Static serialization of the Prisma Compute config. Define app for a single-app repository or apps for a multi-app repository.",
  type: "object",
  additionalProperties: false,
  properties: {
    $schema: { type: "string" },
    region: {
      description:
        "Default region used when creating new apps. Existing apps keep their current region.",
      enum: COMPUTE_REGIONS,
    },
    app: APP_SCHEMA,
    apps: {
      description: "Apps keyed by deploy target name.",
      type: "object",
      minProperties: 1,
      additionalProperties: APP_SCHEMA,
      propertyNames: { minLength: 1 },
    },
  },
  oneOf: [{ required: ["app"] }, { required: ["apps"] }],
} as const;
