const { execSync } = require("child_process");
const fs = require("fs");

const isWin = process.platform === "win32";
const isMac = process.platform === "darwin";
const src = "dist";
const dstWin = "Z:\\docker\\webpage\\frontend\\";
const dstMac = "/Volumes/gahusb.synology.me/docker/webpage/frontend/";
const dst = isWin ? dstWin : dstMac;

if (!fs.existsSync(src)) {
  console.error("dist not found. Run build first.");
  process.exit(1);
}
if (!fs.existsSync(dst)) {
  console.error("NAS path not found. Check mount: " + dst);
  process.exit(1);
}

if (isWin) {
  const cmd =
    'powershell -NoProfile -ExecutionPolicy Bypass -Command "$ErrorActionPreference=\\"Stop\\"; $src=\\"dist\\"; $dst=\\"Z:\\\\docker\\\\webpage\\\\frontend\\\\\\"; if(!(Test-Path $src)){ throw \\"dist not found. Run build first.\\" }; if(!(Test-Path $dst)){ throw \\"NAS drive not found. Check Z: mapping.\\" }; $log = Join-Path (Get-Location) \\"robocopy.log\\"; robocopy $src $dst /MIR /R:1 /W:1 /E /NFL /NDL /NP /V /TEE /LOG:$log; $rc = $LASTEXITCODE; if($rc -ge 8){ Write-Host \\"robocopy failed with code $rc. See $log\\"; exit $rc } else { exit 0 }"';
  execSync(cmd, { stdio: "inherit" });
} else if (isMac) {
  const sshTarget = process.env.NAS_SSH_TARGET;
  const sshPath =
    process.env.NAS_SSH_PATH || "/volume1/docker/webpage/frontend/";
  const sshPort = process.env.NAS_SSH_PORT;
  if (sshTarget) {
    const sshCmd = sshPort ? `ssh -p ${sshPort}` : "ssh";
    execSync(
      `rsync -r --delete --delete-delay -e \"${sshCmd}\" ${src}/ ${sshTarget}:${sshPath}`,
      { stdio: "inherit" }
    );
    process.exit(0);
  }
  // rsync on macOS + SMB/NAS can be flaky; use ditto after a safe clean.
  if (!dst.includes("docker/webpage/frontend")) {
    console.error("Safety check failed: unexpected dst path: " + dst);
    process.exit(1);
  }
  try {
    const testPath = `${dst}.deploy-write-test`;
    fs.writeFileSync(testPath, "ok");
    fs.unlinkSync(testPath);
  } catch (err) {
    console.error(
      "NAS write test failed. Files may be locked or permissions are read-only."
    );
    console.error(
      "Try stopping services using the folder, remounting the share with write access,",
      "or set NAS_SSH_TARGET to deploy over SSH instead."
    );
    throw err;
  }
  const sleep = (ms) =>
    Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
  const retry = (fn, attempts = 6) => {
    for (let i = 0; i < attempts; i += 1) {
      try {
        fn();
        return;
      } catch (err) {
        if (i === attempts - 1) throw err;
        sleep(150);
      }
    }
  };
  const removeTree = (target) => {
    const stat = fs.lstatSync(target);
    if (stat.isDirectory()) {
      retry(() => {
        const entries = fs.readdirSync(target);
        for (const entry of entries) {
          removeTree(`${target}/${entry}`);
        }
      });
      retry(() => fs.rmdirSync(target));
    } else {
      retry(() => fs.unlinkSync(target));
    }
  };
  if (process.env.NAS_CLEAN === "1") {
    try {
      const entries = fs.readdirSync(dst);
      for (const entry of entries) {
        removeTree(`${dst}${entry}`);
      }
    } catch (err) {
      console.warn("Clean skipped due to NAS lock:", err?.message ?? err);
    }
  }
  execSync(`ditto ${src} ${dst}`, { stdio: "inherit" });
} else {
  const baseArgs = ["rsync", "-r", "--delete", "--delete-delay", "-t"];
  const cmd = `${baseArgs.join(" ")} ${src}/ ${dst}`;
  execSync(cmd, { stdio: "inherit" });
}
