import { spawnSync } from "child_process";

type ArgValue = string | boolean;

const WORKFLOW_ARG_KEYS = new Set([
  "mode",
  "target",
  "step",
  "from",
  "executionId",
]);

const parseArgs = (argv: string[]): Record<string, ArgValue> => {
  const args: Record<string, ArgValue> = {};
  for (let index = 0; index < argv.length; index += 1) {
    const item = argv[index];
    if (!item.startsWith("--")) continue;

    const equalIndex = item.indexOf("=");
    if (equalIndex > 2) {
      args[item.slice(2, equalIndex)] = item.slice(equalIndex + 1);
      continue;
    }

    const key = item.slice(2);
    const next = argv[index + 1];
    if (!next || next.startsWith("--")) {
      args[key] = true;
    } else {
      args[key] = next;
      index += 1;
    }
  }
  return args;
};

const stringArg = (
  args: Record<string, ArgValue>,
  key: string,
): string | undefined => {
  const value = args[key];
  return typeof value === "string" && value.length > 0 ? value : undefined;
};

const args = parseArgs(process.argv.slice(2));
const network = stringArg(args, "network") || "hardhat";
const task = stringArg(args, "task") || process.env.WORKFLOW_TASK;

const workflowArgs = Object.fromEntries(
  Object.entries(args).filter(([key]) => WORKFLOW_ARG_KEYS.has(key)),
);

const hardhatArgs = ["hardhat", "run", "scripts/workflow/run.ts", "--network", network];
if (args["no-compile"] === true) {
  hardhatArgs.push("--no-compile");
}

const env = {
  ...process.env,
  WORKFLOW_ARGS_JSON: JSON.stringify(workflowArgs),
  ...(task ? { WORKFLOW_TASK: task } : {}),
};

const npx = process.platform === "win32" ? "npx.cmd" : "npx";
const result = spawnSync(npx, hardhatArgs, {
  env,
  stdio: "inherit",
});

if (result.error) {
  console.error(result.error);
  process.exitCode = 1;
} else {
  process.exitCode = result.status ?? 1;
}
