import { spawn } from "node:child_process";
import type { IncidentAgentRequest, IncidentDispatchLauncher, IncidentLaunchReceipt } from "./incident-launcher";

export function createSystemdLauncher(opts: {
  runnerPath: string;
  deployDir: string;
  configDir: string;
}): IncidentDispatchLauncher {
  return {
    async launch(request: IncidentAgentRequest): Promise<IncidentLaunchReceipt> {
      const unit = `overdeck-incident-${request.incidentId}.service`;

      return new Promise((resolve, reject) => {
        const proc = spawn("systemd-run", [
          "--user",
          `--unit=${unit}`,
          "--property=Restart=no",
          `--property=RuntimeMaxSec=${request.timeoutSeconds + 60}`,
          "--property=MemoryMax=4G",
          `--setenv=OVERDECK_DEPLOY_DIR=${opts.deployDir}`,
          `--setenv=OVERDECK_CONFIG_DIR=${opts.configDir}`,
          "bun", "run", opts.runnerPath, request.incidentId,
        ], {
          stdio: "ignore",
          detached: true,
        });

        proc.on("error", (err) => {
          reject(new Error(`systemd-run failed: ${err.message}`));
        });

        proc.on("close", (exitCode) => {
          if (exitCode === 0) {
            resolve({
              dispatchId: request.dispatchId,
              unit,
              acceptedAt: new Date().toISOString(),
            });
          } else {
            reject(new Error(`systemd-run exited ${exitCode}`));
          }
        });

        proc.unref();
      });
    },
  };
}
