#!/usr/bin/env node
/**
 * Build the rmfshare.exe Windows Share-target activation helper (C46).
 *
 * Mirrors build-rmfmailto-exe.js: hooked into `npm run build`, skips when
 *   - not on Windows,
 *   - the .NET SDK isn't installed (uses the checked-in bin/rmfshare.exe),
 *   - the shipped exe is newer than every file in bin/rmfshare-src/.
 *
 * On a real rebuild runs `dotnet publish -c Release -r win-x64` (NativeAOT —
 * needs the VS C++ toolchain; vswhere's dir is appended to PATH because the
 * ILCompiler targets shell out to it) and copies the published exe to
 * bin/rmfshare.exe. The exe is checked into git so `npm install -g` ships
 * it without requiring .NET on install machines.
 */

import fs from "node:fs";
import path from "node:path";
import { execSync, spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const SRC_DIR = path.join(__dirname, "rmfshare-src");
const BUILT_EXE = path.join(SRC_DIR, "bin", "Release", "net10.0-windows10.0.19041.0", "win-x64", "publish", "rmfshare.exe");
const SHIPPED_EXE = path.join(__dirname, "rmfshare.exe");

if (process.platform !== "win32") {
    console.log("[rmfshare] non-Windows host — skipping (binary is Win-only)");
    process.exit(0);
}

try {
    execSync("dotnet --version", { stdio: "pipe" });
} catch {
    console.log("[rmfshare] dotnet not found — skipping build (using checked-in bin/rmfshare.exe).");
    process.exit(0);
}

// mtime gate — same shape as build-rmfmailto-exe.js.
function newestMtime(dir) {
    let newest = 0;
    const stack = [dir];
    while (stack.length) {
        const d = stack.pop();
        for (const name of fs.readdirSync(d)) {
            if (name === "bin" || name === "obj") continue; // dotnet output dirs
            const full = path.join(d, name);
            const st = fs.statSync(full);
            if (st.isDirectory()) stack.push(full);
            else if (st.mtimeMs > newest) newest = st.mtimeMs;
        }
    }
    return newest;
}

const srcMtime = newestMtime(SRC_DIR);
let shippedMtime = 0;
try { shippedMtime = fs.statSync(SHIPPED_EXE).mtimeMs; } catch { /* missing */ }
if (shippedMtime > srcMtime) {
    console.log("[rmfshare] up-to-date — skipping dotnet publish");
    process.exit(0);
}

console.log("[rmfshare] building (dotnet publish NativeAOT)...");
const t0 = Date.now();
const vswhereDir = "C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer";
const r = spawnSync("dotnet", ["publish", "-c", "Release", "-r", "win-x64"], {
    cwd: SRC_DIR,
    stdio: "inherit",
    shell: true,
    env: { ...process.env, PATH: `${process.env.PATH};${vswhereDir}` },
});
if (r.status !== 0) {
    console.error(`[rmfshare] dotnet publish failed (exit ${r.status})`);
    process.exit(r.status || 1);
}
fs.copyFileSync(BUILT_EXE, SHIPPED_EXE);
const sec = ((Date.now() - t0) / 1000).toFixed(1);
console.log(`[rmfshare] built and copied to bin/rmfshare.exe (${sec}s)`);
