#!/usr/bin/env node
/**
 * Spawns: java -jar <sonarqube-mcp.jar> [extra args...]
 *
 * JAR resolution (first match wins):
 *   1. SONARQUBE_MCP_JAR — explicit path
 *   2. Bundled vendor/sonarqube-mcp-server.jar (shipped with npm)
 *
 * Optional:
 *   JAVA_BIN — java executable (default "java", or JAVA_HOME/bin/java if JAVA_HOME set)
 *   SONARQUBE_JAVA_OPTS — space-separated JVM args before -jar (e.g. -Xmx512m)
 *
 * CLI args after the script are appended after the jar (application args).
 */
import { spawn } from "node:child_process";
import path from "node:path";
import process from "node:process";
import { prepareJarPathForExecution, resolveSonarqubeJar } from "../lib/resolve-sonar-jar.mjs";

const jar = resolveSonarqubeJar();
if (!jar) {
  console.error(
    "[mcp-sonarqube-launcher] No SonarQube MCP JAR found. Install a published package that includes vendor/, or set SONARQUBE_MCP_JAR."
  );
  process.exit(1);
}

const prepared = prepareJarPathForExecution(jar);
const jarToRun = prepared.path;

let javaBin = process.env.JAVA_BIN?.trim();
if (!javaBin && process.env.JAVA_HOME) {
  javaBin = path.join(process.env.JAVA_HOME, "bin", "java");
  if (process.platform === "win32") {
    javaBin += ".exe";
  }
}
if (!javaBin) {
  javaBin = "java";
}

const passthrough = process.argv.slice(2);
const javaOptsRaw = process.env.SONARQUBE_JAVA_OPTS?.trim();
const jvmExtras = javaOptsRaw ? javaOptsRaw.split(/\s+/).filter(Boolean) : [];

const argv = [...jvmExtras, "-jar", jarToRun, ...passthrough];

const child = spawn(javaBin, argv, {
  stdio: "inherit",
  env: process.env,
  windowsHide: true,
});

function forward(sig) {
  try {
    child.kill(sig);
  } catch {
    /* ignore */
  }
  prepared.cleanup?.();
}
for (const sig of ["SIGINT", "SIGTERM"]) {
  process.on(sig, () => forward(sig));
}

child.on("error", (err) => {
  prepared.cleanup?.();
  console.error("[mcp-sonarqube-launcher]", err.message);
  process.exit(1);
});

child.on("exit", (code, signal) => {
  prepared.cleanup?.();
  if (signal) process.exit(1);
  process.exit(code ?? 1);
});
