#!/usr/bin/env node
// HWLAB #803 noise-capture CLI.
//
// Captures the rendered Agent workspace (#code-agent-summary, per-message
// meta/pending/runtime/session/trace cards) from a live or local Cloud Web
// build and prints a structured JSON dump that can be diffed before/after a
// Web UI refactor.
//
// Usage:
//   CHROMIUM_PATH=/usr/bin/chromium-browser \
//     node tools/capture-issue-803-noise.mjs \
//       --url http://74.48.78.17:17666/ --user admin --pass hwlab2026 \
//       --png /tmp/hwlab-noise.png
//   CHROMIUM_PATH=/usr/bin/chromium-browser \
//     NOISE_USER=admin NOISE_PASS=hwlab2026 \
//     node tools/capture-issue-803-noise.mjs

import { setTimeout as sleep } from "node:timers/promises";

import { importPlaywright, launchChromium } from "../scripts/src/browser-launcher.mjs";

function parseArgs(argv) {
  const args = {
    url: process.env.NOISE_URL ?? "http://74.48.78.17:17666/",
    user: process.env.NOISE_USER ?? "admin",
    pass: process.env.NOISE_PASS ?? "hwlab2026",
    message: process.env.NOISE_MESSAGE ?? null,
    viewport: process.env.NOISE_VIEWPORT ?? "1440x900",
    png: process.env.NOISE_PNG ?? "/tmp/hwlab-noise.png"
  };
  for (let index = 0; index < argv.length; index += 1) {
    const arg = argv[index];
    if (arg === "--url") args.url = argv[++index];
    else if (arg === "--user") args.user = argv[++index];
    else if (arg === "--pass") args.pass = argv[++index];
    else if (arg === "--message") args.message = argv[++index];
    else if (arg === "--png") args.png = argv[++index];
    else if (arg === "--viewport") args.viewport = argv[++index];
  }
  const [w, h] = args.viewport.split("x").map(Number);
  args.viewportWidth = Number.isFinite(w) ? w : 1440;
  args.viewportHeight = Number.isFinite(h) ? h : 900;
  return args;
}

const args = parseArgs(process.argv.slice(2));
const { chromium } = await importPlaywright();
const browser = await launchChromium(chromium);
console.error(`[noise] browser ${JSON.stringify(browser.hwlabLaunchPlan ?? {})}`);
const ctx = await browser.newContext({ viewport: { width: args.viewportWidth, height: args.viewportHeight } });
const page = await ctx.newPage();
await page.goto(args.url, { waitUntil: "networkidle", timeout: 30000 });
try {
  await page.locator("#login-username").fill(args.user, { timeout: 5000 });
  await page.locator("#login-password").fill(args.pass);
  await page.locator("#login-submit").click();
  await page.locator("#command-input").waitFor({ state: "visible", timeout: 12000 });
} catch (error) {
  console.error("[noise] login failed:", error instanceof Error ? error.message : String(error));
}
await page.waitForTimeout(1500);
if (args.message) {
  try {
    await page.locator("#command-input").fill(args.message, { timeout: 5000 });
    await page.locator("#command-send").click();
    await sleep(8000);
  } catch (error) {
    console.error("[noise] submit failed:", error instanceof Error ? error.message : String(error));
  }
}

const data = await page.evaluate(() => {
  const summary = document.querySelector("#code-agent-summary");
  const summaryRect = summary?.getBoundingClientRect();
  const summaryText = summary?.textContent?.replace(/\s+/gu, " ").trim().slice(0, 800) ?? null;
  const summaryDetail = document.querySelector("#code-agent-summary-detail");
  const summaryDetailRect = summaryDetail?.getBoundingClientRect();
  const summaryDetailText = summaryDetail?.textContent?.replace(/\s+/gu, " ").trim().slice(0, 1500) ?? null;
  const summaryIsOpen = summary ? summary.open === true : null;
  const summaryDebugBtn = document.querySelector("#code-agent-debug-trigger");
  const convList = document.querySelector("#conversation-list");
  const convListRect = convList?.getBoundingClientRect();
  const messages = [...document.querySelectorAll(".message-card")].map((card) => {
    const rect = card.getBoundingClientRect();
    const role = card.getAttribute("data-message-role")
      ?? [...card.classList].find((cls) => cls.startsWith("message-"))?.replace(/^message-/, "")
      ?? null;
    const meta = card.querySelector(".message-meta")?.textContent?.replace(/\s+/gu, " ").trim() ?? null;
    const pending = card.querySelector(".message-pending-context")?.textContent?.replace(/\s+/gu, " ").trim().slice(0, 600) ?? null;
    const session = card.querySelector(".message-session-context")?.textContent?.replace(/\s+/gu, " ").trim().slice(0, 600) ?? null;
    const runtime = card.querySelector(".message-runtime-path")?.textContent?.replace(/\s+/gu, " ").trim().slice(0, 600) ?? null;
    const trace = card.querySelector(".message-trace")?.textContent?.replace(/\s+/gu, " ").trim().slice(0, 400) ?? null;
    const traceEventsRect = card.querySelector(".message-trace-events")?.getBoundingClientRect();
    const debugTrigger = card.querySelector(".debug-dialog-trigger");
    const cardWidth = rect.width;
    const tracePct = cardWidth > 0 && traceEventsRect ? Math.round((traceEventsRect.width / cardWidth) * 100) : null;
    return {
      role,
      meta,
      pending,
      session,
      runtime,
      trace,
      debugTriggerText: debugTrigger?.textContent ?? null,
      cardWidth: Math.round(cardWidth),
      traceEventsWidth: traceEventsRect ? Math.round(traceEventsRect.width) : null,
      traceEventsPct: tracePct
    };
  });
  const systemCount = messages.filter((m) => m.role === "system").length;
  const roleCounts = messages.reduce((acc, m) => {
    const key = m.role ?? "unknown";
    acc[key] = (acc[key] ?? 0) + 1;
    return acc;
  }, {});
  return {
    summaryText,
    summaryDetailText,
    summaryIsOpen,
    summaryDebugBtnExists: !!summaryDebugBtn,
    summaryRect: summaryRect ? { width: Math.round(summaryRect.width), height: Math.round(summaryRect.height) } : null,
    summaryDetailRect: summaryDetailRect ? { width: Math.round(summaryDetailRect.width), height: Math.round(summaryDetailRect.height) } : null,
    convListRect: convListRect ? { width: Math.round(convListRect.width), height: Math.round(convListRect.height) } : null,
    messageCount: messages.length,
    systemMessageCount: systemCount,
    roleCounts,
    messages
  };
});
console.log(JSON.stringify(data, null, 2));
await page.screenshot({ path: args.png, fullPage: false });
await browser.close();
