export function applyNodeRuntimeDeployYamlOverlay(document: Record<string, unknown>, overlay: Record<string, unknown>): Record<string, unknown> {
  const doc = structuredClone(document);
  const nodeId = requiredString(overlay.nodeId, "overlay.nodeId");
  const laneId = requiredString(overlay.lane, "overlay.lane");
  const nodes = record(doc.nodes);
  const node = record(nodes[nodeId]);
  nodes[nodeId] = { ...node, gitopsRoot: overlay.gitopsRoot, sourceRepo: overlay.gitUrl };
  doc.nodes = nodes;
  const lanes = record(doc.lanes);
  const lane = record(lanes[laneId]);
  const envRecipe = record(lane.envRecipe);
  const downloadStack = {
    ...record(envRecipe.downloadStack),
    httpProxy: overlay.dockerProxyHttp,
    httpsProxy: overlay.dockerProxyHttps,
    noProxy: overlay.dockerNoProxyList,
  };
  const nextLane: Record<string, unknown> = {
    ...lane,
    node: nodeId,
    sourceBranch: overlay.sourceBranch,
    gitopsBranch: overlay.gitopsBranch,
    namespace: overlay.runtimeNamespace,
    endpoint: overlay.publicApiUrl,
    publicEndpoints: { frontend: overlay.publicWebUrl, api: overlay.publicApiUrl },
    artifactCatalog: overlay.catalogPath,
    runtimePath: overlay.runtimePath,
    imageTagMode: "full",
    sourceRepo: overlay.gitUrl,
    observability: overlay.observability,
    envRecipe: { ...envRecipe, downloadStack },
  };
  if (overlay.externalPostgres === undefined || overlay.externalPostgres === null) delete nextLane.externalPostgres;
  else nextLane.externalPostgres = overlay.externalPostgres;
  if (overlay.runtimeStore !== undefined) nextLane.runtimeStore = overlay.runtimeStore;
  if (overlay.codeAgentRuntime !== undefined) nextLane.codeAgentRuntime = overlay.codeAgentRuntime;
  delete nextLane.gitMirror;
  lanes[laneId] = nextLane;
  doc.lanes = lanes;
  return doc;
}

export function nodeRuntimeDeployYamlOverlayShellScript(): string[] {
  return [
    "node - \"$overlay_b64\" <<'NODE_UNIDESK_DEPLOY_OVERLAY'",
    "const fs = require('fs');",
    "const YAML = require('yaml');",
    `const applyNodeRuntimeDeployYamlOverlay = ${applyNodeRuntimeDeployYamlOverlay.toString()};`,
    `const record = ${record.toString()};`,
    `const requiredString = ${requiredString.toString()};`,
    "const overlay = JSON.parse(Buffer.from(process.argv[2], 'base64').toString('utf8'));",
    "const path = 'deploy/deploy.yaml';",
    "const doc = YAML.parse(fs.readFileSync(path, 'utf8'));",
    "fs.writeFileSync(path, YAML.stringify(applyNodeRuntimeDeployYamlOverlay(doc, overlay)));",
    "NODE_UNIDESK_DEPLOY_OVERLAY",
  ];
}

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

function requiredString(value: unknown, label: string): string {
  if (typeof value !== "string" || value.length === 0) throw new Error(`${label} must be a non-empty string`);
  return value;
}
