import { afterEach, expect, test } from "bun:test";
import { spawnSync } from "node:child_process";
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";

const roots: string[] = [];
const script = resolve(import.meta.dir, "runtime-gitops-verify.mjs");

afterEach(() => {
  while (roots.length > 0) rmSync(roots.pop()!, { recursive: true, force: true });
});

test("accepts YAML-owned tool Secret and Kafka env on the cloud-api workload", () => {
  const root = mkdtempSync(join(tmpdir(), "runtime-gitops-verify-"));
  roots.push(root);
  mkdirSync(join(root, "runtime"));
  writeFileSync(join(root, "runtime", "cloud-api.yaml"), deploymentYaml({ ...toolSecretEnv(), ...kafkaEnv() }));
  writeFileSync(join(root, "overlay.json"), JSON.stringify({
    runtimePath: "runtime",
    codeAgentRuntime: {
      enabled: true,
      toolSecretNames: toolSecretNames(),
      kafkaEventBridge: { enabled: true, ...kafkaValues() },
    },
  }));

  const result = spawnSync(process.execPath, [script], {
    cwd: root,
    env: { ...process.env, UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE: join(root, "overlay.json") },
    encoding: "utf8",
  });

  expect(result.status).toBe(0);
  expect(result.stderr).toContain('"code-agent-runtime-tool-secret-env"');
  expect(result.stderr).toContain('"code-agent-runtime-kafka-event-bridge-enabled"');
});

test("rejects missing YAML-owned Kafka env before GitOps publish", () => {
  const root = mkdtempSync(join(tmpdir(), "runtime-gitops-verify-"));
  roots.push(root);
  mkdirSync(join(root, "runtime"));
  writeFileSync(join(root, "runtime", "cloud-api.yaml"), deploymentYaml({ ...kafkaEnv(), HWLAB_KAFKA_CLIENT_ID: undefined }));
  writeFileSync(join(root, "overlay.json"), JSON.stringify({
    runtimePath: "runtime",
    codeAgentRuntime: { enabled: true, kafkaEventBridge: { enabled: true, ...kafkaValues() } },
  }));

  const result = spawnSync(process.execPath, [script], {
    cwd: root,
    env: { ...process.env, UNIDESK_RUNTIME_GITOPS_OVERLAY_FILE: join(root, "overlay.json") },
    encoding: "utf8",
  });

  expect(result.status).toBe(48);
  expect(result.stderr).toContain('"reason":"code-agent-runtime-kafka-env-invalid"');
  expect(result.stderr).toContain('"name":"HWLAB_KAFKA_CLIENT_ID"');
});

function kafkaValues() {
  return {
    bootstrapServers: "kafka.platform-infra.svc.cluster.local:9092",
    stdioTopic: "agentrun.stdio.v1",
    agentRunEventTopic: "agentrun.event.v1",
    hwlabEventTopic: "hwlab.event.v1",
    clientId: "hwlab-production",
  };
}

function toolSecretNames() {
  return {
    githubPr: "agentrun-release-tool-github-pr",
    unideskSsh: "agentrun-release-tool-unidesk-ssh",
  };
}

function toolSecretEnv(): Record<string, string> {
  const names = toolSecretNames();
  return {
    HWLAB_CODE_AGENT_AGENTRUN_GITHUB_TOOL_SECRET_NAME: names.githubPr,
    HWLAB_CODE_AGENT_AGENTRUN_UNIDESK_SSH_TOOL_SECRET_NAME: names.unideskSsh,
  };
}

function kafkaEnv(): Record<string, string | undefined> {
  const kafka = kafkaValues();
  return {
    HWLAB_KAFKA_BOOTSTRAP_SERVERS: kafka.bootstrapServers,
    HWLAB_KAFKA_STDIO_TOPIC: kafka.stdioTopic,
    HWLAB_KAFKA_AGENTRUN_EVENT_TOPIC: kafka.agentRunEventTopic,
    HWLAB_KAFKA_EVENT_TOPIC: kafka.hwlabEventTopic,
    HWLAB_KAFKA_CLIENT_ID: kafka.clientId,
  };
}

function deploymentYaml(env: Record<string, string | undefined>) {
  const entries = Object.entries(env)
    .filter((entry): entry is [string, string] => entry[1] !== undefined)
    .map(([name, value]) => `            - name: ${name}\n              value: ${value}`)
    .join("\n");
  return `apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: hwlab-cloud-api\n  labels:\n    app.kubernetes.io/name: hwlab-cloud-api\nspec:\n  template:\n    spec:\n      containers:\n        - name: hwlab-cloud-api\n          env:\n${entries}\n`;
}
