// One moment of Starlock's real cutscene (public/ideas/starlock/.tests/cutscene-demo.html), drawn by
// headless Chromium on a phone-sized page at a pixel ratio of 2, saved as a lossless PNG. Run it from a
// checkout's root to see that checkout's cutscene (that's how the before and after pictures were made).
//
//   node --input-type=module < research/2026-10-22-starlock-glow/code/cutframe.mjs.txt <beat-id> <out.png> [width height dpr]
//
// (named .txt because the site serves code/ as text; see README.md). beat-id: fleets, rift, drift,
// charge, charge2, lock or title (its still moment, as the game's own shots script uses).
import { spawn } from 'node:child_process';
import { createRequire } from 'node:module';
import net from 'node:net';
import path from 'node:path';

const require = createRequire(path.join(process.cwd(), 'x.js'));
const { chromium } = (() => {
  for (const id of [process.env.PLAYWRIGHT, 'playwright', '/opt/node-tools/node_modules/playwright'].filter(Boolean)) {
    try { return require(id); } catch {}
  }
  throw new Error('Playwright not found: set PLAYWRIGHT to its path.');
})();
const [beat, out, w = '390', h = '844', dpr = '2'] = process.argv.slice(2);
const { BEATS } = await import(path.join(process.cwd(), 'public/ideas/starlock/cutscene.js'));
const b = BEATS.find((x) => x.id === beat);
if (!b) throw new Error(`no beat ${beat}: ${BEATS.map((x) => x.id).join(', ')}`);
const port = await new Promise((r) => { const s = net.createServer().listen(0, () => { const { port } = s.address(); s.close(() => r(port)); }); });
const srv = spawn(process.execPath, [path.join(process.cwd(), 'public/ideas/starlock/.tests/serve.mjs'), String(port)], { stdio: 'ignore' });
const url = `http://127.0.0.1:${port}/ideas/starlock/.tests/cutscene-demo.html`;
for (let i = 0; i < 100 && !(await fetch(url).then((r) => r.ok, () => false)); i++) await new Promise((r) => setTimeout(r, 50));
const browser = await chromium.launch({ args: ['--use-gl=angle', '--use-angle=swiftshader', '--enable-unsafe-swiftshader'] });
try {
  const page = await browser.newPage({ viewport: { width: +w, height: +h }, deviceScaleFactor: +dpr });
  await page.goto(`${url}?render=3d&n=4&t=0`);
  await page.waitForFunction(() => document.body.dataset.ready === '1', null, { timeout: 120000 });
  await page.evaluate((t) => { window.__frame(t - 50); window.__frame(t); }, b.still);
  await page.screenshot({ path: out, timeout: 120000 });
} finally { await browser.close(); srv.kill(); }
