import { randomBytes } from "node:crypto";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";

const pkgRoot = path.join(path.dirname(fileURLToPath(import.meta.url)), "..");
const bundledJar = path.join(pkgRoot, "vendor", "sonarqube-mcp-server.jar");

export function resolveSonarqubeJar() {
  const fromEnv = process.env.SONARQUBE_MCP_JAR?.trim();
  if (fromEnv) return fromEnv;
  if (fs.existsSync(bundledJar)) return bundledJar;
  return null;
}

/**
 * On Windows, `java -jar` keeps a mandatory lock on the JAR path. That breaks `npx`/`npm`
 * updates which rename files under `node_modules` (EBUSY). If we are using the **bundled**
 * vendor JAR, copy it to %TEMP% and run from there so the copy under `vendor/` is never
 * opened by the JVM.
 *
 * @param {string} jarPath path returned by {@link resolveSonarqubeJar}
 * @returns {{ path: string, cleanup?: () => void }}
 */
export function prepareJarPathForExecution(jarPath) {
  if (process.platform !== "win32") {
    return { path: jarPath };
  }
  let resolved;
  let bundledResolved;
  try {
    resolved = path.resolve(jarPath);
    bundledResolved = path.resolve(bundledJar);
  } catch {
    return { path: jarPath };
  }
  if (resolved !== bundledResolved) {
    return { path: jarPath };
  }
  const tmp = path.join(os.tmpdir(), `sq-mcp-${randomBytes(8).toString("hex")}.jar`);
  fs.copyFileSync(bundledResolved, tmp);
  return {
    path: tmp,
    cleanup() {
      try {
        fs.unlinkSync(tmp);
      } catch {
        /* ignore */
      }
    },
  };
}
