import { createReadStream, existsSync, statSync } from "node:fs";
import { createServer } from "node:http";
import { extname, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
import { createGameApiHandler } from "./game-api.mjs";

const distPath = fileURLToPath(new URL("../dist", import.meta.url));
const indexPath = resolve(distPath, "index.html");
const host = process.env.HOST ?? "127.0.0.1";
const port = Number(process.env.PORT ?? 4173);
const contentTypes = {
  ".css": "text/css; charset=utf-8",
  ".glb": "model/gltf-binary",
  ".html": "text/html; charset=utf-8",
  ".ico": "image/x-icon",
  ".jpeg": "image/jpeg",
  ".jpg": "image/jpeg",
  ".js": "text/javascript; charset=utf-8",
  ".json": "application/json; charset=utf-8",
  ".png": "image/png",
  ".svg": "image/svg+xml",
  ".webp": "image/webp",
};

function sendFile(response, filePath) {
  response.statusCode = 200;
  response.setHeader("Content-Type", contentTypes[extname(filePath).toLowerCase()] ?? "application/octet-stream");
  response.setHeader("X-Content-Type-Options", "nosniff");
  response.setHeader("Referrer-Policy", "same-origin");
  response.setHeader("X-Frame-Options", "DENY");
  createReadStream(filePath).pipe(response);
}

function serveStatic(request, response) {
  let requestPath;
  try { requestPath = decodeURIComponent(new URL(request.url, "http://localhost").pathname); }
  catch { response.statusCode = 400; return response.end("Bad request"); }
  const candidate = resolve(distPath, `.${requestPath}`);
  const insideDist = candidate === distPath || candidate.startsWith(`${distPath}${sep}`);
  if (insideDist && existsSync(candidate) && statSync(candidate).isFile()) return sendFile(response, candidate);
  if (!existsSync(indexPath)) {
    response.statusCode = 503;
    return response.end("Build missing. Run pnpm build.");
  }
  return sendFile(response, indexPath);
}

const api = createGameApiHandler();
const server = createServer((request, response) => {
  void api.handle(request, response, () => serveStatic(request, response));
});

server.listen(port, host, () => console.log(`I Want To Heal listening on http://${host}:${port}`));

function shutdown() {
  server.close(() => {
    api.close();
    process.exit(0);
  });
}
process.on("SIGINT", shutdown);
process.on("SIGTERM", shutdown);
