import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { after, before, test } from "node:test";

import { createServer } from "vite";

let server;
let createRecordedOpenWatchdog;
let recordedOpenWatchdogTimeoutMs;
let rerunViewerInitialSource;
let resolveRecordedViewerSourceUrl;

before(async () => {
  server = await createServer({
    appType: "custom",
    logLevel: "silent",
    server: { middlewareMode: true },
  });
  ({
    createRecordedOpenWatchdog,
    recordedOpenWatchdogTimeoutMs,
    rerunViewerInitialSource,
    resolveRecordedViewerSourceUrl,
  } = await server.ssrLoadModule("/src/components/RerunViewport.tsx"));
});

after(async () => {
  await server?.close();
});

const sourceUrl = "/api/v1/observation-sessions/session-atomic/recording.rrd";
const sha256 = "a".repeat(64);
const viewerSourceUrl = `${sourceUrl}?generation=${sha256}`;

test("only the canonical digest-bound generation URL reaches the native Rerun receiver", () => {
  const descriptor = {
    sourceUrl,
    viewerSourceUrl,
    byteLength: 246_331_680,
    sha256,
  };
  const resolved = resolveRecordedViewerSourceUrl(descriptor, "http://mission-core.test");
  assert.equal(resolved, `http://mission-core.test${viewerSourceUrl}`);
  assert.equal(rerunViewerInitialSource(resolved), resolved);

  for (const unsafeViewerSourceUrl of [
    sourceUrl,
    `${sourceUrl}?generation=${"b".repeat(64)}`,
    `${viewerSourceUrl}&extra=true`,
    `https://foreign.test${viewerSourceUrl}`,
  ]) {
    assert.throws(
      () => resolveRecordedViewerSourceUrl({
        ...descriptor,
        viewerSourceUrl: unsafeViewerSourceUrl,
      }, "http://mission-core.test"),
      /Unsafe recorded RRD viewer descriptor/,
    );
  }
});

test("recorded admission watchdog is size-aware and exits an incomplete load", () => {
  const smallDelay = recordedOpenWatchdogTimeoutMs(4);
  const currentDelay = recordedOpenWatchdogTimeoutMs(246_331_680);
  const largeDelay = recordedOpenWatchdogTimeoutMs(805_687_122);
  assert.ok(smallDelay >= 120_000);
  assert.ok(currentDelay >= smallDelay);
  assert.ok(largeDelay > currentDelay);
  assert.ok(largeDelay <= 1_800_000);
  assert.ok(largeDelay > 12_000);

  let scheduledCallback;
  let scheduledDelay;
  let timeoutCount = 0;
  const cancelled = [];
  const watchdog = createRecordedOpenWatchdog({
    byteLength: 246_331_680,
    schedule(callback, timeoutMs) {
      scheduledCallback = callback;
      scheduledDelay = timeoutMs;
      return 17;
    },
    cancel(handle) {
      cancelled.push(handle);
    },
    onTimeout() {
      timeoutCount += 1;
    },
  });
  watchdog.arm();
  assert.equal(watchdog.pending(), true);
  assert.equal(scheduledDelay, currentDelay);
  scheduledCallback();
  assert.equal(timeoutCount, 1);
  assert.equal(watchdog.pending(), false);
  assert.deepEqual(cancelled, []);
});

test("complete recorded admission clears its watchdog", () => {
  let timeoutCount = 0;
  const cancelled = [];
  const watchdog = createRecordedOpenWatchdog({
    byteLength: 805_687_122,
    schedule() {
      return 23;
    },
    cancel(handle) {
      cancelled.push(handle);
    },
    onTimeout() {
      timeoutCount += 1;
    },
  });
  watchdog.arm();
  watchdog.clear();
  assert.equal(watchdog.pending(), false);
  assert.equal(timeoutCount, 0);
  assert.deepEqual(cancelled, [23]);
});

test("recorded RRD bytes are never split across LogChannel.send_rrd calls", async () => {
  const source = await readFile(
    new URL("../src/components/RerunViewport.tsx", import.meta.url),
    "utf8",
  );
  assert.doesNotMatch(source, /streamVerifiedRecordedRrd/);
  assert.doesNotMatch(source, /missioncore\/recorded-recording/);
  assert.doesNotMatch(source, /recordedChannel/);
  assert.match(source, /viewer\.start\(\s*rerunViewerInitialSource\(resolvedSource\)/s);
  assert.match(
    source,
    /recordingOpened = true;[\s\S]*if \(!isRecordedSource\) clearLiveRecordingOpenTimer\(\);/,
  );
  assert.match(
    source,
    /viewerStartResolved = true;\s*if \(isRecordedSource && !recordedSceneAdmitted\) recordedOpenWatchdog\?\.arm\(\);/,
  );
  assert.match(
    source,
    /if \(readyToRender && !readyPublished\)[\s\S]*clearRecordedAdmissionWatchdog\(\);/,
  );
});

test("the complete vendor canvas host is hidden during partial and failed admission", async () => {
  const css = await readFile(new URL("../src/styles/spatial.css", import.meta.url), "utf8");
  assert.match(
    css,
    /\.rerun-viewport:is\(\[data-status="loading"\], \[data-status="error"\]\)\s+\.rerun-viewport__canvas\s*\{[^}]*visibility:\s*hidden;[^}]*pointer-events:\s*none;/s,
  );
  assert.doesNotMatch(
    css,
    /data-status="loading"[^}]*\.rerun-viewport__canvas\s*>\s*div/s,
  );
});
