import { createHash } from "node:crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { parseSaveProbe } from "./index.ts";

type CliOptions = {
  savePath: string;
  outPath: string | null;
  compact: boolean;
  validateLsuAuburn: boolean;
};

const options = parseArgs(process.argv.slice(2));
const sourceHash = createHash("sha256")
  .update(readFileSync(options.savePath))
  .digest("hex");
const result = await parseSaveProbe(options.savePath, {
  sourceHash,
  archivePath: options.savePath,
  openedAt: new Date().toISOString()
});
const json = options.compact
  ? JSON.stringify(result)
  : `${JSON.stringify(result, null, 2)}\n`;

if (options.outPath) {
  mkdirSync(dirname(options.outPath), { recursive: true });
  writeFileSync(options.outPath, json, "utf-8");
} else {
  process.stdout.write(json);
}

if (options.validateLsuAuburn) {
  const validation = result.validation.lsuAuburn;
  const passed =
    validation?.found === true &&
    validation.scoreMatched &&
    validation.houstonAndersonMatched &&
    validation.julianReeseMatched;

  if (passed) {
    process.stderr.write(
      `LSU/Auburn validation passed for SeasonGame row ${validation.gameRow}.\n`
    );
  } else {
    process.stderr.write(
      `LSU/Auburn validation failed: ${JSON.stringify(validation, null, 2)}\n`
    );
    process.exitCode = 2;
  }
}

function parseArgs(args: string[]): CliOptions {
  let savePath: string | null = null;
  let outPath: string | null = null;
  let compact = false;
  let validateLsuAuburn = false;

  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--out") {
      const value = args[index + 1];
      if (!value) throw new Error("--out requires a path.");
      outPath = resolve(value);
      index += 1;
      continue;
    }
    if (arg === "--compact") {
      compact = true;
      continue;
    }
    if (arg === "--validate-lsu-auburn") {
      validateLsuAuburn = true;
      continue;
    }
    if (arg === "--help" || arg === "-h") {
      printUsageAndExit(0);
    }
    if (arg.startsWith("-")) {
      throw new Error(`Unknown option: ${arg}`);
    }
    if (savePath) throw new Error(`Unexpected argument: ${arg}`);
    savePath = resolve(arg);
  }

  if (!savePath) printUsageAndExit(1);
  if (!existsSync(savePath)) throw new Error(`Save file does not exist: ${savePath}`);

  return {
    savePath,
    outPath,
    compact,
    validateLsuAuburn
  };
}

function printUsageAndExit(exitCode: number): never {
  process.stderr.write(
    [
      "Usage: npm run parse:save -- <savePath> [--out out/parser/latest-snapshot.json] [--validate-lsu-auburn] [--compact]",
      "",
      "Examples:",
      "  npm run parse:save -- saves/DYNASTY-QQ2 --validate-lsu-auburn",
      "  npm run parse:save -- saves/DYNASTY-QQ2 --out out/parser/latest-snapshot.json"
    ].join("\n")
  );
  process.stderr.write("\n");
  process.exit(exitCode);
}
