import { existsSync } from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";

function getCodesignArgs() {
  const identity = process.env.ELECTROBUN_DEVELOPER_ID || "-";
  const args = ["--force", "--deep"];

  if (identity !== "-") {
    args.push("--options", "runtime", "--timestamp");
  }

  args.push("--sign", identity);
  return { identity, args };
}

export function codesignMacAppBundle(appBundlePath) {
  if (process.platform !== "darwin") {
    console.log("codesign-macos-app: skipping (not macOS)");
    return;
  }

  if (!appBundlePath || !existsSync(appBundlePath)) {
    throw new Error(`codesign-macos-app: app bundle not found: ${appBundlePath}`);
  }

  const contentsPath = path.join(appBundlePath, "Contents");
  if (!existsSync(contentsPath)) {
    throw new Error(`codesign-macos-app: invalid app bundle: ${appBundlePath}`);
  }

  const { identity, args } = getCodesignArgs();
  const result = spawnSync("codesign", [...args, appBundlePath], {
    stdio: "inherit",
  });

  if (result.status !== 0) {
    throw new Error(
      `codesign failed with exit code ${result.status ?? 1}`,
    );
  }

  const verify = spawnSync(
    "codesign",
    ["--verify", "--deep", "--strict", "--verbose=2", appBundlePath],
    { encoding: "utf8" },
  );

  if (verify.status !== 0) {
    throw new Error(
      `codesign verify failed: ${verify.stderr || verify.stdout || "unknown error"}`,
    );
  }

  const label = identity === "-" ? "ad-hoc" : identity;
  console.log(`codesign-macos-app: signed ${appBundlePath} (${label})`);
}

function resolveAppBundlePath() {
  const fromEnv = process.env.ELECTROBUN_WRAPPER_BUNDLE_PATH;
  if (fromEnv && existsSync(fromEnv)) {
    return path.resolve(fromEnv);
  }

  const fromArgv = process.argv[2];
  if (fromArgv && existsSync(fromArgv)) {
    return path.resolve(fromArgv);
  }

  return null;
}

const invokedPath = process.argv[1]
  ? path.resolve(process.argv[1])
  : null;
const modulePath = fileURLToPath(import.meta.url);

if (invokedPath === modulePath) {
  const appBundlePath = resolveAppBundlePath();
  if (!appBundlePath) {
    console.error(
      "codesign-macos-app: set ELECTROBUN_WRAPPER_BUNDLE_PATH or pass app bundle path",
    );
    process.exit(1);
  }

  codesignMacAppBundle(appBundlePath);
}
