import { copyFileSync, existsSync, mkdirSync, chmodSync, statSync } from "node:fs";
import { basename, delimiter, dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";

const scriptDirectory = dirname(fileURLToPath(import.meta.url));
const projectRoot = resolve(scriptDirectory, "..");
const binariesDirectory = join(projectRoot, "src-tauri", "binaries");
const extension = process.platform === "win32" ? ".exe" : "";

function defaultTargetTriple() {
  const triples = {
    "win32:x64": "x86_64-pc-windows-msvc",
    "win32:arm64": "aarch64-pc-windows-msvc",
    "linux:x64": "x86_64-unknown-linux-gnu",
    "linux:arm64": "aarch64-unknown-linux-gnu",
    "darwin:x64": "x86_64-apple-darwin",
    "darwin:arm64": "aarch64-apple-darwin",
  };
  return triples[`${process.platform}:${process.arch}`];
}

function executableCandidates() {
  const configured = process.env.GIT_LFS_BINARY?.trim();
  if (configured) return [configured];

  const pathEntries = (process.env.PATH ?? "")
    .split(delimiter)
    .filter(Boolean);
  const candidates = pathEntries.map((entry) => join(entry, `git-lfs${extension}`));
  if (process.platform === "win32") {
    for (const entry of pathEntries) {
      if (basename(entry).toLowerCase() === "cmd") {
        candidates.push(resolve(entry, "..", "mingw64", "bin", "git-lfs.exe"));
      }
    }
  }
  return candidates;
}

const source = executableCandidates()
  .filter((candidate) => existsSync(candidate))
  // Git for Windows exposes a small launcher in cmd/ and the standalone
  // executable in mingw64/bin/. The standalone file is the portable sidecar.
  .sort((left, right) => statSync(right).size - statSync(left).size)[0];
if (!source) {
  throw new Error(
    "Git LFS was not found. Install git-lfs or set GIT_LFS_BINARY before building Gitty.",
  );
}

const targetTriple = (
  process.env.GITTY_TARGET_TRIPLE
  ?? process.env.TAURI_ENV_TARGET_TRIPLE
  ?? process.env.TARGET
  ?? defaultTargetTriple()
)?.trim();
if (!targetTriple) throw new Error("Rust did not report a target triple.");

mkdirSync(binariesDirectory, { recursive: true });

const developmentTarget = join(binariesDirectory, `git-lfs${extension}`);
const bundleTarget = join(
  binariesDirectory,
  `git-lfs-${targetTriple}${extension}`,
);
for (const target of [developmentTarget, bundleTarget]) {
  if (resolve(source) !== resolve(target)) copyFileSync(source, target);
  if (process.platform !== "win32") chmodSync(target, 0o755);
}

console.log(`Prepared bundled git-lfs from ${source} for ${targetTriple}.`);
