import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

import { test } from "bun:test";

import { pk01CaddyMergeManagedBlocksPython } from "./pk01-caddy";

function mergeCaddyfiles(current: string, desired: string, legacyDomains: readonly string[] = []): { merged: string; summary: Record<string, unknown> } {
  const dir = mkdtempSync(join(tmpdir(), "pk01-caddy-"));
  try {
    const currentPath = join(dir, "current.Caddyfile");
    const desiredPath = join(dir, "desired.Caddyfile");
    const mergedPath = join(dir, "merged.Caddyfile");
    writeFileSync(currentPath, current, "utf8");
    writeFileSync(desiredPath, desired, "utf8");
    const result = spawnSync("python3", ["-", desiredPath, currentPath, mergedPath, ...legacyDomains], {
      encoding: "utf8",
      input: pk01CaddyMergeManagedBlocksPython(),
    });
    assert.equal(result.status, 0, result.stderr || result.stdout);
    return {
      merged: readFileSync(mergedPath, "utf8"),
      summary: JSON.parse(result.stdout) as Record<string, unknown>,
    };
  } finally {
    rmSync(dir, { recursive: true, force: true });
  }
}

test("PK01 Caddy merge preserves monitor root nested managed block", () => {
  const current = `{
  email ops@pikapython.com
}

pikapython.com, www.pikapython.com {
  reverse_proxy 127.0.0.1:18888
}

api2.pikapython.com {
  reverse_proxy 127.0.0.1:18080
}

# BEGIN unidesk managed langbot
langbot.pikapython.com {
  reverse_proxy 127.0.0.1:22097
}
# END unidesk managed langbot

# BEGIN unidesk managed sub2api-jd01
api2.pikapython.com {
  reverse_proxy 127.0.0.1:22080
}
# END unidesk managed sub2api-jd01

monitor.pikapython.com {
    # BEGIN unidesk managed hwlab-web-probe-sentinel-active-root
    handle {
        reverse_proxy 127.0.0.1:22098
    }
    # END unidesk managed hwlab-web-probe-sentinel-active-root
}
`;
  const desired = `{
  email ops@pikapython.com
}

pikapython.com, www.pikapython.com {
  reverse_proxy 127.0.0.1:18888
}

# BEGIN unidesk managed sub2api-jd01
api2.pikapython.com {
  reverse_proxy 127.0.0.1:22087
}
# END unidesk managed sub2api-jd01
`;

  const { merged, summary } = mergeCaddyfiles(current, desired, ["api2.pikapython.com"]);

  assert.equal(summary.baseSource, "current");
  assert.match(merged, /monitor\.pikapython\.com \{/u);
  assert.match(merged, /hwlab-web-probe-sentinel-active-root/u);
  assert.match(merged, /reverse_proxy 127\.0\.0\.1:22098/u);
  assert.match(merged, /# BEGIN unidesk managed langbot/u);
  assert.match(merged, /# BEGIN unidesk managed sub2api-jd01[\s\S]*127\.0\.0\.1:22087/u);
  assert.doesNotMatch(merged, /127\.0\.0\.1:22080/u);
  assert.doesNotMatch(merged, /127\.0\.0\.1:18080/u);
});
