import minimist from "minimist";

const ARGS = {
  string: [
    "lib-schema",
    "shard",
    "shards",
    "schema",
    "factor",
    "from",
    "to",
    "deactivate-sql",
    "max-replication-lag-sec",
    "parallelism",
    "dsn",
    "dsns",
    "decommission",
    "decomission",
    "activate",
    "activate-on-destination",
    "weight-sql",
    "migrate-cmd",
    "schema-name-fmt",
  ],
  boolean: ["verbose", "wait", "skip-config", "json", "validate-fks"],
} as const;

export type Args = Record<"_", string[]> &
  Record<(typeof ARGS)["string"][number], string | undefined> &
  Record<(typeof ARGS)["boolean"][number], boolean | undefined> & {
    ["--"]: string[];
  };

/**
 * An improved version of minimist parsing that also populates the _ array with
 * "unknown" args and options.
 */
export function parseArgs(argsIn: string[]): Args {
  const args = minimist(argsIn, JSON.parse(JSON.stringify(ARGS)));
  args._ = [];
  for (argsIn = [...argsIn]; argsIn.length > 0; ) {
    const arg = argsIn.shift()!;
    if (ARGS.boolean.find((b) => arg === `--${b}` || arg === `--no-${b}`)) {
      continue;
    } else if (ARGS.string.find((s) => arg === `--${s}`)) {
      argsIn.shift();
      continue;
    } else if (ARGS.string.find((s) => arg.startsWith(`--${s}=`))) {
      continue;
    } else {
      args._.push(arg);
    }
  }

  return args as unknown as Args;
}
