#!/usr/bin/env bun

import { spawnSync } from "node:child_process";
import { readFileSync, realpathSync } from "node:fs";
import { dirname, isAbsolute, join, resolve } from "node:path";

import { buildPublicEdgeArchiveReconcile } from "../../src/platform-infra-public-edge.ts";

const options = parseOptions(process.argv.slice(2));
const sourceRoot = realpathSync(options.sourceRoot);
const archiveRoot = dirname(sourceRoot);
const markerCommit = readFileSync(join(archiveRoot, ".unidesk-source-commit"), "utf8").trim();
if (markerCommit !== options.sourceCommit) fail("archive source commit marker 不匹配");
const ancestryFile = join(archiveRoot, ".unidesk-source-ancestors");
const ancestors = readFileSync(ancestryFile, "utf8").split(/\r?\n/u).filter(Boolean);
if (!ancestors.includes(options.sourceCommit) || ancestors.some((value) => !/^[0-9a-f]{40}$/u.test(value))) fail("archive ancestry proof 无效");
const configPath = resolve(sourceRoot, options.config);
if (!configPath.startsWith(`${sourceRoot}/`)) fail("--config 必须位于 source archive 内");

const reconcile = buildPublicEdgeArchiveReconcile({
  configPath,
  targetId: options.target,
  authorityId: options.authority,
  sourceCommit: options.sourceCommit,
  ancestry: ancestors,
});
const result = spawnSync("sh", [], {
  cwd: sourceRoot,
  env: { ...process.env, UNIDESK_TRANS_REPO_ROOT: sourceRoot },
  input: reconcile.script,
  stdio: ["pipe", "inherit", "inherit"],
  timeout: 120_000,
});
process.exit(result.status ?? 1);

function parseOptions(args) {
  const values = new Map();
  let confirm = false;
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--confirm") {
      confirm = true;
      continue;
    }
    if (!["--source-root", "--source-commit", "--authority", "--config", "--target"].includes(arg)) fail(`不支持的参数：${arg}`);
    const value = args[index + 1];
    if (value === undefined || value.startsWith("--")) fail(`${arg} 需要参数`);
    values.set(arg.slice(2), value);
    index += 1;
  }
  const sourceRoot = values.get("source-root");
  const sourceCommit = values.get("source-commit");
  const authority = values.get("authority");
  const config = values.get("config");
  const target = values.get("target");
  if (!confirm) fail("必须显式传入 --confirm");
  if (typeof sourceRoot !== "string" || !isAbsolute(sourceRoot)) fail("--source-root 必须是绝对路径");
  if (typeof sourceCommit !== "string" || !/^[0-9a-f]{40}$/u.test(sourceCommit)) fail("--source-commit 必须是 40 位 commit");
  if (typeof authority !== "string" || authority.length === 0) fail("缺少 --authority");
  if (typeof config !== "string" || isAbsolute(config)) fail("--config 必须是 archive 内相对路径");
  if (typeof target !== "string" || target.length === 0) fail("缺少 --target");
  return { sourceRoot, sourceCommit, authority, config, target };
}

function fail(message) {
  process.stderr.write(`${JSON.stringify({ ok: false, action: "platform-infra-public-edge-archive-reconcile", error: message, valuesPrinted: false })}\n`);
  process.exit(1);
}
