import { spawn } from "node:child_process";
import { readFile } from "node:fs/promises";
import { join, resolve } from "node:path";
import { appendRetainedLog, createProductionServer, productionPort } from "./host-lib.mjs";

const installDir = resolve(import.meta.dirname, "..");
const appDir = join(installDir, "app");
const configPath = process.env.CODE_REMOTE_MANAGER_CONFIG_PATH || join(process.env.LOCALAPPDATA, "CodeRemoteManager", "config.local.json");
const config = JSON.parse(await readFile(configPath, "utf8"));
const logsDir = join(process.env.LOCALAPPDATA, "CodeRemoteManager", "logs");
process.env.CODE_REMOTE_MANAGER_CONFIG_PATH = configPath;

let backend;
let stopping = false;

function startBackend() {
  backend = spawn(process.execPath, [join(appDir, "backend", "src", "index.js")], {
    cwd: appDir,
    env: { ...process.env, CODE_REMOTE_MANAGER_MANAGED_HOST: "1" },
    windowsHide: true,
    stdio: ["ignore", "pipe", "pipe"]
  });
  backend.stdout.on("data", (chunk) => { void appendRetainedLog(logsDir, "backend", chunk).catch(() => {}); });
  backend.stderr.on("data", (chunk) => { void appendRetainedLog(logsDir, "backend-error", chunk).catch(() => {}); });
  backend.once("exit", () => { if (!stopping) setTimeout(startBackend, 1500); });
}

const server = createProductionServer({ publicDir: join(appDir, "pwa"), backendPort: config.port });
server.once("error", async (error) => {
  await appendRetainedLog(logsDir, "host-error", error.message).catch(() => {});
  process.exit(error.code === "EADDRINUSE" ? 0 : 1);
});
server.listen(productionPort(), "127.0.0.1", startBackend);

for (const signal of ["SIGINT", "SIGTERM"]) process.on(signal, () => {
  stopping = true;
  server.close();
  backend?.kill();
  process.exit(0);
});
