// The render sidecar: a minimal internal HTTP service the backend calls to rasterize the
// finished-game export image. It runs the same drawGameImage the browser build ships
// (bundled from ui/src/lib at image build time) on skia-canvas, with system fonts from
// the image (Liberation Sans + Noto Color Emoji via fontconfig).
//
//   POST /render  {game, moves, alphabet, labels, dateLocale, hostname, scale?} → image/png
//   GET  /healthz → 200
//
// The service is internal-only (docker network `internal`); authentication, participant
// checks and the signed public URL all live in the backend — this process only draws.
import { createServer } from 'node:http';
import { renderRequest } from './render.mjs';

const PORT = Number(process.env.RENDERER_PORT || 8090);
// A render request is a finished game's journal — generously capped.
const MAX_BODY = 2 * 1024 * 1024;

function readBody(req) {
  return new Promise((resolve, reject) => {
    const chunks = [];
    let size = 0;
    req.on('data', (c) => {
      size += c.length;
      if (size > MAX_BODY) {
        reject(Object.assign(new Error('body too large'), { status: 413 }));
        req.destroy();
        return;
      }
      chunks.push(c);
    });
    req.on('end', () => resolve(Buffer.concat(chunks)));
    req.on('error', reject);
  });
}

const server = createServer(async (req, res) => {
  try {
    if (req.method === 'GET' && req.url === '/healthz') {
      res.writeHead(200, { 'content-type': 'text/plain' }).end('ok');
      return;
    }
    if (req.method === 'POST' && req.url === '/render') {
      const png = await renderRequest(JSON.parse(await readBody(req)));
      res.writeHead(200, { 'content-type': 'image/png', 'content-length': png.length }).end(png);
      return;
    }
    res.writeHead(404).end();
  } catch (err) {
    const status = err.status || (err instanceof SyntaxError ? 400 : 500);
    console.error(`render error: ${err.message}`);
    res.writeHead(status, { 'content-type': 'text/plain' }).end('render failed');
  }
});

server.listen(PORT, () => console.log(`renderer listening on :${PORT}`));
