import { mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { describe, expect, test } from "bun:test";
import { resolveSentinelChildJson } from "./hwlab-node-web-sentinel-cicd-shared";
import { sentinelDeliveryStatus, type SentinelCicdState } from "./hwlab-node-web-sentinel-cicd";

describe("sentinel CI/CD child JSON recovery", () => {
  test("recovers remote probe JSON from trans truncation dump", () => {
    const dir = join(tmpdir(), `unidesk-sentinel-cicd-${Date.now()}-${process.pid}`);
    mkdirSync(dir, { recursive: true });
    const dumpPath = join(dir, "stdout.json");
    writeFileSync(dumpPath, JSON.stringify({
      ok: true,
      present: true,
      digest: "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      valuesRedacted: true,
    }));
    const summary = {
      stdout: {
        stream: "stdout",
        truncated: true,
        dumpPath,
        valuesRedacted: true,
      },
      valuesRedacted: true,
    };
    const resolved = resolveSentinelChildJson({
      stdout: "tail fragment that is not json",
      stderr: `UNIDESK_SSH_TRUNCATION_SUMMARY ${JSON.stringify(summary)}\n`,
      exitCode: 0,
      timedOut: false,
    }, "web-probe-sentinel-test-probe");
    expect(resolved.parsed?.ok).toBe(true);
    expect(resolved.parsed?.present).toBe(true);
    expect(resolved.diagnostics.stdoutKind).toBe("ssh-truncation-summary");
    expect(resolved.diagnostics.dumpPath).toBe(dumpPath);
    expect(resolved.diagnostics.source).toBe("dump");
  });
});

test("sentinel delivery status distinguishes cadence convergence without blocking", () => {
  const commit = "f87cd3ac8fd2494f9dfed51e7d8ececd3fc42939";
  const state = { sourceHead: { commit } } as unknown as SentinelCicdState;
  const base = {
    sourceMirror: { ok: true },
    registry: { probe: { present: true } },
    gitMirror: { ok: true },
    gitops: { ok: true, sourceCommit: commit, schedule: "0 */2 * * *", revision: "gitops-revision" },
    argo: { ok: true, syncStatus: "Synced", healthStatus: "Healthy" },
    runtime: { ok: true, probe: { deployment: { sourceCommit: commit } } },
  };
  const converging = sentinelDeliveryStatus(state, { ...base, cadence: { ok: false, probe: { schedule: "0 * * * *" } } }, "pipeline-run");
  expect(converging.outcome).toBe("converging");
  expect(converging.blocking).toBe(false);
  const converged = sentinelDeliveryStatus(state, { ...base, cadence: { ok: true, probe: { schedule: "0 */2 * * *" } } }, "pipeline-run");
  expect(converged.outcome).toBe("converged");
  expect(converged.desiredSourceCommit).toBe(commit);
});
