// Browser. Does the game's FLIP flip at 60 fps, hold at 30 fps and in still mode, and how much does the picture
// change from one frame to the next? The cutscene demo in headless Chromium (SwiftShader), held at one moment,
// with the animation clock (document.timeline) faked to step 16.67 or 33.3 ms per frame.
//   node --input-type=module - <repo-root> < flipcheck.mjs.txt      (PLAYWRIGHT=/path/to/playwright if needed)
import { spawn } from "node:child_process";
import { createRequire } from "node:module";
import path from "node:path";
const require = createRequire(import.meta.url);
const pw = require(process.env.PLAYWRIGHT || "playwright");
const repo = process.argv[2] || ".";
const root = path.resolve(repo, "public/ideas/starlock/.tests");
const port = 47123;
const srv = spawn(process.execPath, [path.join(root, "serve.mjs"), String(port)], { stdio: "ignore" });
await new Promise((r) => setTimeout(r, 800));
const browser = await pw.chromium.launch({ args: ["--use-angle=swiftshader", "--enable-unsafe-swiftshader"] });
for (const [step, extra] of [[16.67, ''], [33.3, ''], [16.67, '&still=1']]) {
  const page = await browser.newPage({ viewport: { width: 390, height: 844 } });
  page.on("pageerror", (e) => console.log("pageerror", e.message));
  await page.addInitScript((step) => { let c = 0; Object.defineProperty(document.timeline, "currentTime", { get: () => (c += step) }); }, step);
  await page.goto(`http://127.0.0.1:${port}/ideas/starlock/.tests/cutscene-demo.html?render=3d&n=4&t=9000&paint=full${extra}`);
  await page.waitForSelector("body[data-ready]", { timeout: 60000 });
  const flips = await page.evaluate(async () => {
    const { FLIP } = await import("../reveal3d.js"); const seen = [];
    for (let i = 0; i < 80; i++) { window.__frame(9000); if (i >= 70) seen.push(FLIP.value); }
    return seen;
  });
  const a = await page.screenshot({ timeout: 300000 });
  await page.evaluate(() => window.__frame(9000));
  const b = await page.screenshot({ timeout: 300000 });
  await page.evaluate(() => window.__frame(9000));
  const c = await page.screenshot({ timeout: 300000 });
  const sharp = createRequire(path.resolve(repo, "package.json"))("sharp");
  const raw = async (p) => (await sharp(p).raw().toBuffer());
  const [A, B, C] = await Promise.all([a, b, c].map(raw));
  let dAB = 0, maxAB = 0, dAC = 0;
  for (let i = 0; i < A.length; i++) { const d = Math.abs(A[i] - B[i]); if (d) dAB++; maxAB = Math.max(maxAB, d); if (A[i] !== C[i]) dAC++; }
  console.log(`frame step ${step} ms${extra}: FLIP over frames 70-79 ${flips.join("")}; consecutive frames differ in ${(100 * dAB / A.length).toFixed(1)}% of channels (max ${maxAB}), two apart in ${(100 * dAC / A.length).toFixed(1)}%`);
  await page.close();
}
await browser.close(); srv.kill();
