import { join } from "path";
import { existsSync, mkdirSync, createWriteStream, readFileSync } from "fs";
import { writeFile, readFile } from "fs/promises";
import { get } from "https";
import { $ } from "zx";
import { startingDir } from "./consts";

const findNvmrc = () => {
  const nvmrcPaths = [
    join(startingDir, "..", ".nvmrc"),
    join(startingDir, ".nvmrc"),
  ];
  for (const nvmrcPath of nvmrcPaths) {
    if (existsSync(nvmrcPath)) {
      return nvmrcPath;
    }
  }
  throw new Error("NVMRC file not found");
}
// Read Node.js version from .nvmrc
const NVMRC_PATH = findNvmrc();
console.log(`NVMRC_PATH: ${NVMRC_PATH}`);
const NODE_VERSION = readFileSync(NVMRC_PATH, "utf8").trim();

const NODE_FILENAME = `node-v${NODE_VERSION}-linux-x64.tar.xz`;
const NODE_URL = `https://nodejs.org/download/release/v${NODE_VERSION}/${NODE_FILENAME}`;
const NODE_DEST = join(startingDir, "source", "dynamix.unraid.net", "usr", "local");
const NODE_VERSION_FILE = join(NODE_DEST, ".node-version");

async function fetchFile(url: string, dest: string) {
  return new Promise((resolve, reject) => {
    const file = createWriteStream(dest);
    get(url, (response) => {
      if (response.statusCode !== 200) {
        reject(new Error(`Failed to get '${url}' (${response.statusCode})`));
        return;
      }
      response.pipe(file);
      file.on("finish", () => file.close(resolve));
      file.on("error", reject);
    }).on("error", reject);
  });
}

export async function ensureNodeJs() {
  let currentVersion: string | null = null;
  if (existsSync(NODE_VERSION_FILE)) {
    currentVersion = (await readFile(NODE_VERSION_FILE, "utf8")).trim();
  }
  if (currentVersion !== NODE_VERSION) {
    mkdirSync(NODE_DEST, { recursive: true });
    if (!existsSync(NODE_FILENAME)) {
      await fetchFile(NODE_URL, NODE_FILENAME);
    }
    // Extract Node.js excluding include/node and share/doc/node directories
    await $`tar --strip-components=1 -xf ${NODE_FILENAME} --exclude="*/include/node" --exclude="*/share/doc/node" --exclude="*/README.md" --exclude="*/LICENSE" --exclude="*/CHANGELOG.md" -C ${NODE_DEST}`;
    await writeFile(NODE_VERSION_FILE, NODE_VERSION, "utf8");
  }
} 