// SPEC: PJ2026-01060307 控制面模块化 draft-2026-06-25-p0. options module for scripts/src/platform-infra.ts.

// Moved mechanically from scripts/src/platform-infra.ts:338-453 for #903.

import { createHash, randomBytes } from "node:crypto";
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, isAbsolute, join } from "node:path";
import type { UniDeskConfig } from "../config";
import { rootPath } from "../config";
import { startJob } from "../jobs";
import type { RenderedCliResult } from "../output";
import { pk01CaddyMergeManagedBlocksPython, renderCaddyManagedBlock, renderSimpleReverseProxyCaddySiteBlock } from "../pk01-caddy";
import { capture, compactCapture, parseJsonOutput, prepareFrpcSecret, shQuote } from "../platform-infra-public-service";
import { yamlBooleanField, yamlFieldLabel, yamlIntegerField } from "../platform-infra-ops-library";
import { fingerprintSecretValues, parseEnvFile, readEnvSourceFile, readTextFile, redactRepoPath, requiredEnvValue } from "../secrets";

import { apply, plan, status } from "./actions";
import { defaultSub2ApiTargetId, readSub2ApiConfig, validateOptions } from "./config";
import { configPath, platformInfraHelp, serviceName } from "./entry";
import { imagePrepull } from "./image-prepull";
import { isHostDockerTarget, resolveTarget } from "./manifest";
import { rollout, rolloutSmoke } from "./rollout";
import { validate } from "./policy";

export function sub2ApiHelpTargetSummary(): Record<string, unknown> {
  const sub2api = readSub2ApiConfig();
  const target = resolveTarget(sub2api, sub2api.defaults.targetId);
  return {
    default: sub2api.defaults.targetId,
    namespace: target.namespace,
    service: serviceName,
    runtimeMode: target.runtimeMode,
    serviceDns: isHostDockerTarget(target) ? `host-docker:127.0.0.1:${target.hostDocker?.appPort ?? 0}` : `${serviceName}.${target.namespace}.svc.cluster.local:8080`,
    exposure: target.publicExposure?.enabled === true ? "yaml-controlled-public-exposure" : "k3s-cluster-internal-only",
    resourceLimits: "unset-by-policy",
    versionConfigPath: configPath,
  };
}

export async function runPlatformInfraCommand(config: UniDeskConfig, args: string[]): Promise<Record<string, unknown> | RenderedCliResult> {
  const [target, action] = args;
  if (target === "public-edge") {
    const { runPlatformInfraPublicEdgeCommand } = await import("../platform-infra-public-edge");
    return await runPlatformInfraPublicEdgeCommand(config, args.slice(1));
  }
  if (target === "sub2rank") {
    const { runSub2RankCommand } = await import("../platform-infra-sub2rank");
    return await runSub2RankCommand(config, args.slice(1));
  }
  if (target === "egress-proxy") {
    const { runPlatformInfraEgressProxyCommand } = await import("../platform-infra-egress-proxy");
    return await runPlatformInfraEgressProxyCommand(config, args.slice(1));
  }
  if (target === "langbot") {
    const { runLangBotCommand } = await import("../platform-infra-langbot");
    return await runLangBotCommand(config, args.slice(1));
  }
  if (target === "nginx") {
    const { runPlatformInfraNginxCommand } = await import("../platform-infra-nginx");
    return await runPlatformInfraNginxCommand(config, args.slice(1));
  }
  if (target === "n8n") {
    const { runN8nCommand } = await import("../platform-infra-n8n");
    return await runN8nCommand(config, args.slice(1));
  }
  if (target === "temporal") {
    const { runTemporalCommand } = await import("../platform-infra-temporal");
    return await runTemporalCommand(config, args.slice(1));
  }
  if (target === "selfmedia-voice") {
    const { runSelfMediaVoiceCommand } = await import("../platform-infra-selfmedia-voice");
    return await runSelfMediaVoiceCommand(config, args.slice(1));
  }
  if (target === "webterm") {
    const { runWebtermCommand } = await import("../platform-infra-webterm");
    return await runWebtermCommand(config, args.slice(1));
  }
  if (target === "wechat-archive") {
    const { runWechatArchiveCommand } = await import("../platform-infra-wechat-archive");
    return await runWechatArchiveCommand(config, args.slice(1));
  }
  if (target === "observability") {
    const { runPlatformObservabilityCommand } = await import("../platform-infra-observability");
    return await runPlatformObservabilityCommand(config, args.slice(1));
  }
  if (target === "secret-plane") {
    const { runSecretPlaneCommand } = await import("../platform-infra-secret-plane");
    return await runSecretPlaneCommand(config, args.slice(1));
  }
  if (target === "kafka") {
    const { runPlatformInfraKafkaCommand } = await import("../platform-infra-kafka");
    return await runPlatformInfraKafkaCommand(config, args.slice(1));
  }
  if (target === "gitea") {
    const { runPlatformInfraGiteaCommand } = await import("../platform-infra-gitea");
    return await runPlatformInfraGiteaCommand(config, args.slice(1));
  }
  if (target === "hyperv-vm") {
    const { runPlatformInfraHyperVVmCommand } = await import("../platform-infra-hyperv-vm");
    return await runPlatformInfraHyperVVmCommand(config, args.slice(1));
  }
  if (target === "k3s-cluster") {
    const { runPlatformInfraK3sClusterCommand } = await import("../platform-infra-k3s-cluster");
    return await runPlatformInfraK3sClusterCommand(config, args.slice(1));
  }
  if (target === "pipelines-as-code" || target === "pac") {
    const { runPlatformInfraPipelinesAsCodeCommand } = await import("../platform-infra-pipelines-as-code");
    return await runPlatformInfraPipelinesAsCodeCommand(config, args.slice(1));
  }
  if (target !== "sub2api") return unsupported(args);
  if (action === "plan" || action === undefined) {
    const planArgs = args.slice(2);
    const result = plan(parseTargetOptions(planArgs));
    return planArgs.includes("--full") || planArgs.includes("--raw") ? result : renderSub2ApiPlan(result);
  }
  if (action === "apply") {
    const options = parseApplyOptions(args.slice(2));
    const result = await apply(config, options);
    return options.full || options.raw ? result : renderSub2ApiApply(result);
  }
  if (action === "rollout") {
    const options = parseApplyOptions(args.slice(2));
    const result = await rollout(config, options);
    return options.full || options.raw ? result : renderSub2ApiRollout(result);
  }
  if (action === "smoke") {
    const options = parseDisclosureOptions(args.slice(2));
    const result = await rolloutSmoke(options.targetId);
    return options.full || options.raw ? result : renderSub2ApiSmoke(result);
  }
  if (action === "image-prepull") {
    const options = parseApplyOptions(args.slice(2));
    const result = await imagePrepull(config, options);
    return options.full || options.raw ? result : renderSub2ApiImagePrepull(result);
  }
  if (action === "status") {
    const options = parseDisclosureOptions(args.slice(2));
    const result = await status(config, options);
    return options.full || options.raw ? result : renderSub2ApiStatus(result);
  }
  if (action === "validate") return await validate(config, parseDisclosureOptions(args.slice(2)));
  if (action === "ops") {
    const { runSub2ApiOpsCommand } = await import("../platform-infra-sub2api-ops");
    return await runSub2ApiOpsCommand(config, args.slice(2));
  }
  if (action === "codex-pool") {
    const { runCodexPoolCommand } = await import("../platform-infra-sub2api-codex");
    return await runCodexPoolCommand(config, args.slice(2));
  }
  return unsupported(args);
}

export interface ApplyOptions {
  targetId: string;
  dryRun: boolean;
  confirm: boolean;
  wait: boolean;
  full: boolean;
  raw: boolean;
}

export interface DisclosureOptions {
  targetId: string;
  full: boolean;
  raw: boolean;
}

export interface TargetOptions {
  targetId: string;
}

export interface PolicyCheck {
  name: string;
  ok: boolean;
  detail: string;
}

function renderSub2ApiPlan(result: Record<string, unknown>): RenderedCliResult {
  const target = record(result.target);
  const config = record(record(result.config).target);
  const exposure = record(config.publicExposure);
  const egress = record(config.egressProxy);
  const next = record(result.next);
  const policy = arrayRecords(result.policy);
  const failedPolicy = policy.filter((item) => item.ok === false);
  const rows = [
    ["TARGET", stringValue(target.id), "route", stringValue(target.route)],
    ["NAMESPACE", stringValue(target.namespace), "role", stringValue(target.role)],
    ["DATABASE", stringValue(config.databaseMode), "redis", stringValue(config.redisMode)],
    ["AUTO_SETUP", boolText(record(config.runtime).autoSetup), "mode", stringValue(config.runtimeMode)],
    ["REPLICAS", `${stringValue(config.appReplicas)}/${stringValue(config.redisReplicas)}`, "service", stringValue(target.serviceDns)],
    ["PUBLIC", boolText(exposure.enabled), "url", stringValue(exposure.publicBaseUrl, "-")],
    ["EGRESS", boolText(egress.enabled), "source", `${stringValue(egress.sourceType, "-")} ${stringValue(egress.sourceFingerprint, "-")}`],
    ["POLICY", failedPolicy.length === 0 ? "ok" : `failed=${failedPolicy.length}`, "valuesPrinted", "false"],
  ];
  const lines = [
    "PLATFORM-INFRA SUB2API PLAN",
    ...table(["FIELD", "VALUE", "DETAIL", "VALUE"], rows),
    "",
    "NEXT",
    `  dry-run: ${stringValue(next.dryRun, `bun scripts/cli.ts platform-infra sub2api apply --target ${stringValue(target.id)} --dry-run`)}`,
    `  apply: ${stringValue(next.apply, `bun scripts/cli.ts platform-infra sub2api apply --target ${stringValue(target.id)} --confirm`)}`,
    `  status: ${stringValue(next.status, `bun scripts/cli.ts platform-infra sub2api status --target ${stringValue(target.id)}`)}`,
    "  full: bun scripts/cli.ts platform-infra sub2api plan --target " + stringValue(target.id) + " --full",
    "",
    "Disclosure: default output is bounded; Secret and proxy source values are not printed.",
  ];
  return rendered(result, "platform-infra sub2api plan", lines);
}

function renderSub2ApiStatus(result: Record<string, unknown>): RenderedCliResult {
  const target = record(result.target);
  const summary = record(result.summary);
  const secret = record(summary.secret);
  const egress = record(summary.egressProxy);
  const localHttps = record(summary.localHttpsExposure);
  const networkPolicy = record(summary.networkPolicy);
  const checks = record(summary.checks);
  const isHostDocker = stringValue(summary.runtimeMode, "") === "host-docker";
  const deployments = arrayRecords(summary.deployments)
    .filter((item) => stringValue(item.name).startsWith("sub2api"))
    .map((item) => [
      stringValue(item.name),
      boolText(item.ready),
      `${stringValue(item.readyReplicas, "0")}/${stringValue(item.desired, "0")}`,
      arrayValues(item.images).slice(0, 1).map((value) => stringValue(value)).join(",") || "-",
    ]);
  const containers = arrayRecords(summary.containers)
    .map((item) => [
      stringValue(item.Names, stringValue(item.names)),
      stringValue(item.State, stringValue(item.state)),
      stringValue(item.Status, stringValue(item.status)),
      stringValue(item.Image, stringValue(item.image)),
    ]);
  const services = arrayRecords(summary.services)
    .filter((item) => stringValue(item.name).startsWith("sub2api"))
    .map((item) => [
      stringValue(item.name),
      stringValue(item.type),
      arrayRecords(item.ports).map((port) => `${stringValue(port.name, "port")}:${stringValue(port.port)}`).join(","),
    ]);
  const lines = [
    "PLATFORM-INFRA SUB2API STATUS",
    ...table(["TARGET", "ROUTE", "NAMESPACE", "STATUS"], [[stringValue(summary.target, stringValue(target.id)), stringValue(summary.route, stringValue(target.route)), stringValue(summary.namespace, stringValue(target.namespace)), stringValue(summary.status, result.ok === false ? "failed" : "ok")]]),
    "",
    "WORKLOADS",
    ...(deployments.length > 0
      ? table(["NAME", "READY", "REPLICAS", "IMAGE"], deployments)
      : containers.length > 0
        ? table(["NAME", "STATE", "STATUS", "IMAGE"], containers)
        : ["-"]),
    "",
    "SERVICES",
    ...(services.length === 0 ? ["-"] : table(["NAME", "TYPE", "PORTS"], services)),
    "",
    "CHECKS",
    ...table(["CHECK", "VALUE", "DETAIL"], isHostDocker
      ? [
          ["localHealth", boolText(record(checks.localHealth).exitCode === 0), "http://127.0.0.1 health"],
          ["caddy", boolText(record(checks.caddyService).exitCode === 0), "PK01 Caddy service"],
          ["egressProxy", boolText(egress.enabled === false), "not deployed"],
          ["sentinel", boolText(record(summary.sentinel).enabled === false), "not deployed"],
        ]
      : [
          ["namespace", boolText(summary.namespaceExists), stringValue(summary.namespace)],
          ["secret", boolText(secret.ready), `name=${stringValue(secret.name, "-")} missing=${arrayValues(secret.missingKeys).length}`],
          ["egressProxy", boolText(egress.aligned), `enabled=${boolText(egress.enabled)} valuesPrinted=false`],
          ["localHttps", boolText(localHttps.ok), stringValue(localHttps.publicBaseUrl, "not-enabled")],
          ["networkPolicy", boolText(networkPolicy.ok), `required=${stringValue(networkPolicy.requiredName, "-")}`],
        ]),
    "",
    "NEXT",
    `  validate: bun scripts/cli.ts platform-infra sub2api validate --target ${stringValue(summary.target, stringValue(target.id))}`,
    `  full: bun scripts/cli.ts platform-infra sub2api status --target ${stringValue(summary.target, stringValue(target.id))} --full`,
    "Disclosure: default output is bounded; use --full or --raw for pod/service/event details.",
  ];
  return rendered(result, "platform-infra sub2api status", lines);
}

function renderSub2ApiApply(result: Record<string, unknown>): RenderedCliResult {
  const target = record(result.target);
  const remote = record(result.remote);
  const policy = arrayRecords(result.policy);
  const failedPolicy = policy.filter((item) => item.ok === false);
  const mode = stringValue(result.mode);
  const targetId = stringValue(target.id, stringValue(result.target));
  const route = stringValue(target.route, stringValue(remote.route));
  const namespace = stringValue(target.namespace, "-");
  const status = result.ok === false ? "failed" : "ok";
  const lines = [
    "PLATFORM-INFRA SUB2API APPLY",
    ...table(["TARGET", "ROUTE", "NAMESPACE", "MODE", "STATUS"], [[targetId, route, namespace, mode, status]]),
    "",
    "POLICY",
    failedPolicy.length === 0 ? "ok" : `failed=${failedPolicy.length}`,
  ];

  if (mode === "policy-blocked") {
    lines.push(
      "",
      "FAILED POLICY",
      ...(failedPolicy.length === 0 ? ["-"] : table(["NAME", "DETAIL"], failedPolicy.map((item) => [stringValue(item.name), stringValue(item.detail)]))),
      "",
      "NEXT",
      `  plan: bun scripts/cli.ts platform-infra sub2api plan --target ${targetId}`,
      `  full: bun scripts/cli.ts platform-infra sub2api apply --target ${targetId} --dry-run --full`,
    );
    return rendered(result, "platform-infra sub2api apply", lines);
  }

  if (mode === "async-job") {
    const job = record(result.job);
    const next = record(result.next);
    lines.push(
      "",
      "JOB",
      ...table(["ID", "STATUS", "COMMAND"], [[stringValue(job.id), stringValue(job.status, "started"), stringValue(result.statusCommand)]]),
      "",
      "NEXT",
      `  status: ${stringValue(next.status, stringValue(result.statusCommand))}`,
      `  rollout: ${stringValue(next.rollout, `bun scripts/cli.ts platform-infra sub2api status --target ${targetId}`)}`,
      `  validate: ${stringValue(next.validate, `bun scripts/cli.ts platform-infra sub2api validate --target ${targetId}`)}`,
      `  full: bun scripts/cli.ts platform-infra sub2api apply --target ${targetId} --confirm --wait --full`,
    );
    return rendered(result, "platform-infra sub2api apply", lines);
  }

  lines.push(
    "",
    "REMOTE",
    ...renderApplyRemoteSummary(remote),
  );

  const pk01Exposure = record(result.pk01Exposure);
  if (Object.keys(pk01Exposure).length > 0) {
    lines.push(
      "",
      "PK01_EXPOSURE",
      ...table(["CHECK", "VALUE"], [
        ["ok", boolText(pk01Exposure.ok)],
        ["mode", stringValue(pk01Exposure.mode)],
        ["valuesPrinted", "false"],
      ]),
    );
  }

  const next = record(result.next);
  lines.push(
    "",
    "NEXT",
    `  status: ${stringValue(next.status, `bun scripts/cli.ts platform-infra sub2api status --target ${targetId}`)}`,
    `  validate: ${stringValue(next.validate, `bun scripts/cli.ts platform-infra sub2api validate --target ${targetId}`)}`,
    `  full: bun scripts/cli.ts platform-infra sub2api apply --target ${targetId} ${mode === "confirmed" ? "--confirm --wait" : "--dry-run"} --full`,
    "Disclosure: default output is bounded; use --full or --raw for remote stdout/stderr details.",
  );
  return rendered(result, "platform-infra sub2api apply", lines);
}

function renderSub2ApiImagePrepull(result: Record<string, unknown>): RenderedCliResult {
  const target = record(result.target);
  const mode = stringValue(result.mode);
  const targetId = stringValue(target.id, stringValue(result.target));
  const status = result.ok === false ? "failed" : "ok";
  const lines = [
    "PLATFORM-INFRA SUB2API IMAGE PREPULL",
    ...table(["TARGET", "ROUTE", "NAMESPACE", "MODE", "STATUS"], [[targetId, stringValue(target.route), stringValue(target.namespace), mode, status]]),
  ];
  if (mode === "async-job") {
    const job = record(result.job);
    const next = record(result.next);
    lines.push(
      "",
      "JOB",
      ...table(["ID", "STATUS", "COMMAND"], [[stringValue(job.id), stringValue(job.status, "started"), stringValue(result.statusCommand)]]),
      "",
      "IMAGES",
      ...table(["IMAGE"], arrayValues(result.images).map((image) => [stringValue(image)])),
      "",
      "NEXT",
      `  status: ${stringValue(next.status, stringValue(result.statusCommand))}`,
      `  verify: ${stringValue(next.verify, `bun scripts/cli.ts platform-infra sub2api image-prepull --target ${targetId}`)}`,
      `  apply: ${stringValue(next.apply, `bun scripts/cli.ts platform-infra sub2api apply --target ${targetId} --confirm`)}`,
    );
    return rendered(result, "platform-infra sub2api image-prepull", lines);
  }
  const remote = record(result.remote);
  const imageRows = arrayRecords(remote.images).map((item) => [
    stringValue(item.image),
    stringValue(item.runtime),
    boolText(item.presentBefore),
    boolText(item.presentAfter),
    stringValue(record(item.pull).exitCode, "-"),
    stringValue(item.imageId, "-").slice(0, 24),
  ]);
  const next = record(result.next);
  lines.push(
    "",
    "IMAGES",
    ...(imageRows.length === 0 ? ["-"] : table(["IMAGE", "RUNTIME", "BEFORE", "AFTER", "PULL", "IMAGE_ID"], imageRows)),
    "",
    "CHECKS",
    ...table(["CHECK", "VALUE"], [
      ["ok", boolText(result.ok !== false)],
      ["runtime", stringValue(remote.runtime)],
      ["valuesPrinted", "false"],
    ]),
    "",
    "NEXT",
    `  apply: ${stringValue(next.apply, `bun scripts/cli.ts platform-infra sub2api apply --target ${targetId} --confirm`)}`,
    `  status: ${stringValue(next.status, `bun scripts/cli.ts platform-infra sub2api status --target ${targetId}`)}`,
    `  full: bun scripts/cli.ts platform-infra sub2api image-prepull --target ${targetId} ${mode === "confirmed" ? "--confirm --wait" : "--dry-run"} --full`,
    "Disclosure: default output is bounded; Secret values are not printed.",
  );
  return rendered(result, "platform-infra sub2api image-prepull", lines);
}

function boundedStageText(value: unknown, limit = 120): string {
  const compact = stringValue(value, "").replace(/\s+/gu, " ").trim();
  if (compact.length === 0) return "-";
  return compact.length <= limit ? compact : `${compact.slice(0, Math.max(0, limit - 1))}…`;
}

function stageSucceeded(stage: Record<string, unknown>): boolean {
  if (typeof stage.ok === "boolean") return stage.ok;
  return record(stage.remote).ok === true;
}

function rolloutApplyDetail(stage: Record<string, unknown>): string {
  const remote = record(stage.remote);
  const steps = record(remote.steps);
  const failed = Object.entries(steps)
    .map(([name, value]) => [name, record(value)] as const)
    .filter(([, step]) => typeof step.exitCode === "number" && step.exitCode !== 0);
  if (failed.length === 0) return stringValue(stage.failedStage);
  const manifestApplied = record(steps.apply).exitCode === 0;
  const failures = failed.map(([name, step]) => {
    const reason = boundedStageText(step.stderr, 80);
    return reason === "-" ? name : `${name}:${reason}`;
  }).join(",");
  return `applied=${boolText(manifestApplied)} failed=${failures}`;
}

export function rolloutStageRows(stages: Record<string, unknown>): string[][] {
  return Object.entries(stages).map(([name, value]) => {
    const stage = record(value);
    const ok = stageSucceeded(stage);
    if (name === "smoke") {
      return [name, ok ? "ok" : "failed", stringValue(stage.status), stringValue(stage.requestId, stringValue(stage.reason))];
    }
    if (name === "prepull") {
      const images = arrayRecords(record(stage.remote).images);
      const presence = images.length === 0
        ? "-"
        : images.map((item) => `${stringValue(item.image)}=${boolText(item.presentBefore || item.presentAfter)}`).join(",");
      return [name, ok ? "ok" : "failed", stringValue(stage.mode), presence];
    }
    if (name === "image") {
      return [name, ok ? "ok" : "failed", "runtime-alignment", `${stringValue(stage.desiredImage)} <= ${arrayValues(stage.observedImages).map((item) => stringValue(item)).join(",")}`];
    }
    const detail = name === "apply" && !ok ? rolloutApplyDetail(stage) : stringValue(stage.failedStage);
    return [name, ok ? "ok" : "failed", stringValue(stage.mode, stringValue(stage.action)), detail];
  });
}

function rolloutCurrentImage(stages: Record<string, unknown>): string {
  const summary = record(record(stages.current).summary);
  const containers = arrayRecords(summary.containers);
  const appContainer = containers.find((item) => stringValue(item.Names, stringValue(item.names)) === "sub2api-app");
  if (appContainer !== undefined) return stringValue(appContainer.Image, stringValue(appContainer.image));
  const deployments = arrayRecords(summary.deployments);
  const appDeployment = deployments.find((item) => stringValue(item.name) === "sub2api");
  return appDeployment === undefined ? "-" : arrayValues(appDeployment.images).map((item) => stringValue(item)).join(",");
}

export function renderSub2ApiRollout(result: Record<string, unknown>): RenderedCliResult {
  const target = record(result.target);
  const mode = stringValue(result.mode);
  const targetId = stringValue(target.id);
  const stages = record(result.stages);
  const lines = [
    "PLATFORM-INFRA SUB2API ROLLOUT",
    ...table(["TARGET", "ROUTE", "MODE", "STATUS", "CURRENT_IMAGE", "DESIRED_IMAGE"], [[
      targetId,
      stringValue(target.route),
      mode,
      result.ok === true ? "ok" : "failed",
      rolloutCurrentImage(stages),
      stringValue(result.desiredImage),
    ]]),
  ];
  if (mode === "async-job") {
    const job = record(result.job);
    const next = record(result.next);
    lines.push(
      "",
      "JOB",
      ...table(["ID", "STATUS", "COMMAND"], [[stringValue(job.id), stringValue(job.status, "started"), stringValue(result.statusCommand)]]),
      "",
      "NEXT",
      `  status: ${stringValue(next.status, stringValue(result.statusCommand))}`,
    );
    return rendered(result, "platform-infra sub2api rollout", lines);
  }

  const timings = record(result.timingsMs);
  lines.push(
    "",
    "STAGES",
    ...table(["STAGE", "STATUS", "MODE", "DETAIL"], rolloutStageRows(stages)),
    "",
    "TIMINGS_MS",
    ...table(["PREPULL", "APPLY", "VERIFY", "TOTAL"], [[
      stringValue(timings.prepull),
      stringValue(timings.apply),
      stringValue(timings.verify),
      stringValue(timings.total),
    ]]),
    "",
    "NEXT",
    result.ok === true
      ? `  closeout: add MDTODO/report, commit ${stringValue(result.desiredImage)}, then push master directly (no PR)`
      : `  inspect: bun scripts/cli.ts platform-infra sub2api rollout --target ${targetId} ${mode === "confirmed" ? "--confirm --wait" : "--dry-run"} --full`,
    "Disclosure: account runtime, Codex pool, proxy, and sentinel configuration are not synchronized by rollout.",
  );
  return rendered(result, "platform-infra sub2api rollout", lines);
}

function renderSub2ApiSmoke(result: Record<string, unknown>): RenderedCliResult {
  const target = record(result.target);
  const lines = [
    "PLATFORM-INFRA SUB2API SMOKE",
    ...table(["TARGET", "STATUS", "EXECUTED", "HTTP", "RESPONSE_STATUS", "ELAPSED_MS", "REQUEST_ID"], [[
      stringValue(target.id),
      stringValue(result.status, result.ok === true ? "ok" : "failed"),
      boolText(result.executed),
      stringValue(result.httpStatus),
      stringValue(result.responseStatus),
      stringValue(result.elapsedMs),
      stringValue(result.requestId, stringValue(result.reason)),
    ]]),
    "",
    "Disclosure: the existing consumer key and response body are never printed; valuesPrinted=false.",
  ];
  return rendered(result, "platform-infra sub2api smoke", lines);
}

function renderApplyRemoteSummary(remote: Record<string, unknown>): string[] {
  const steps = record(remote.steps);
  const stepRows = Object.entries(steps).map(([name, value]) => {
    const step = record(value);
    return [name, stringValue(step.exitCode), step.exitCode === 0 ? "ok" : "failed"];
  });
  for (const name of ["clientDryRun", "serverDryRun", "accountLocalProxySecretDryRun"]) {
    const step = record(remote[name]);
    if (step.exitCode !== undefined) stepRows.push([name, stringValue(step.exitCode), step.exitCode === 0 ? "ok" : "failed"]);
  }
  const ports = record(remote.ports);
  const runtime = stringValue(remote.runtimeMode, record(remote.serverDryRun).exitCode !== undefined ? "k3s" : "-");
  const rows = [
    ["ok", boolText(remote.ok), "runtime", runtime],
    ["target", stringValue(remote.target), "route", stringValue(remote.route)],
  ];
  if (remote.namespace !== undefined) rows.push(["namespace", stringValue(remote.namespace), "existsBeforeDryRun", boolText(remote.namespaceExistsBeforeDryRun)]);
  if (remote.image !== undefined || remote.projectName !== undefined) rows.push(["image", stringValue(remote.image), "project", stringValue(remote.projectName)]);
  const lines = [
    ...table(["FIELD", "VALUE", "DETAIL", "VALUE"], rows),
  ];
  if (Object.keys(ports).length > 0) {
    lines.push(
      "",
      "PORTS",
      ...table(["NAME", "VALUE"], [
        ["app", stringValue(ports.app)],
        ["redis", stringValue(ports.redis)],
        ["observed", stringValue(ports.observed).replace(/\s+/gu, " ").trim()],
      ]),
    );
  }
  lines.push(
    "",
    "STEPS",
    ...(stepRows.length === 0 ? ["-"] : table(["STEP", "EXIT", "STATUS"], stepRows)),
    "valuesPrinted=false",
  );
  return lines;
}

function rendered(result: Record<string, unknown>, command: string, lines: string[]): RenderedCliResult {
  return {
    ok: result.ok !== false,
    command,
    renderedText: lines.join("\n"),
    contentType: "text/plain",
  };
}

function record(value: unknown): Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};
}

function arrayRecords(value: unknown): Record<string, unknown>[] {
  return Array.isArray(value) ? value.map(record) : [];
}

function arrayValues(value: unknown): unknown[] {
  return Array.isArray(value) ? value : [];
}

function stringValue(value: unknown, fallback = "-"): string {
  if (value === undefined || value === null || value === "") return fallback;
  return String(value);
}

function boolText(value: unknown): string {
  return value === true ? "yes" : value === false ? "no" : "-";
}

function table(headers: string[], rows: string[][]): string[] {
  const widths = headers.map((header, index) => Math.max(header.length, ...rows.map((row) => row[index]?.length ?? 0)));
  const renderRow = (row: string[]) => row.map((cell, index) => cell.padEnd(widths[index] ?? cell.length)).join("  ").trimEnd();
  return [renderRow(headers), ...rows.map(renderRow)];
}

export function unsupported(args: string[]): Record<string, unknown> {
  return {
    ok: false,
    error: "unsupported-platform-infra-command",
    args,
    help: platformInfraHelp(),
  };
}

export function parseApplyOptions(args: string[]): ApplyOptions {
  const target = parseTargetOptions(args);
  validateOptions(args, new Set(["--dry-run", "--confirm", "--wait", "--target", "--full", "--raw"]));
  if (args.includes("--dry-run") && args.includes("--confirm")) throw new Error("apply accepts only one of --dry-run or --confirm");
  const raw = args.includes("--raw");
  return {
    targetId: target.targetId,
    dryRun: args.includes("--dry-run") || !args.includes("--confirm"),
    confirm: args.includes("--confirm"),
    wait: args.includes("--wait"),
    full: raw || args.includes("--full"),
    raw,
  };
}

export function parseDisclosureOptions(args: string[]): DisclosureOptions {
  const target = parseTargetOptions(args);
  validateOptions(args, new Set(["--full", "--raw", "--target"]));
  const raw = args.includes("--raw");
  return { targetId: target.targetId, full: raw || args.includes("--full"), raw };
}

export function parseTargetOptions(args: string[]): TargetOptions {
  let targetId: string | null = null;
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--target") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--target requires a value");
      targetId = value;
      index += 1;
    } else if (arg.startsWith("--target=")) {
      targetId = arg.slice("--target=".length);
    }
  }
  const resolvedTargetId = targetId ?? defaultSub2ApiTargetId();
  if (!/^[A-Za-z0-9._-]+$/u.test(resolvedTargetId)) throw new Error("--target must be a simple target id");
  return { targetId: resolvedTargetId };
}
