import { expect, test } from "bun:test";
import {
  mergePluginAssets,
  runtimeIdsFromMarkup,
  runtimeScriptsForMarkup,
  servePluginAsset,
} from "../src/plugin-assets.ts";
import { resolvePackageMigrations } from "../src/plugin-migrations.ts";

test("injects only runtimes referenced by rendered markup", () => {
  const runtimes = [
    { id: "captcha", source: "window.captcha = true" },
    { id: "editor", source: "window.editor = true" },
  ];
  const body = '<div data-wrnexus-runtime="captcha captcha"></div>';
  expect([...runtimeIdsFromMarkup(body)]).toEqual(["captcha"]);
  const scripts = runtimeScriptsForMarkup(body, runtimes);
  expect(scripts).toHaveLength(1);
  expect(scripts[0]).toMatchObject({
    src: "/__wrnexus/assets/captcha.js",
    type: "module",
    defer: true,
  });
});

test("serves package assets with a safe content type", async () => {
  const assets = mergePluginAssets(
    [{ id: "captcha", source: "window.captcha = true", type: "script" }],
    [],
  );
  const response = await servePluginAsset(assets, "/__wrnexus/assets/captcha.js", "development");
  expect(response?.status).toBe(200);
  expect(response?.headers.get("content-type")).toBe("text/javascript; charset=utf-8");
  expect(response?.headers.get("x-content-type-options")).toBe("nosniff");
  expect(await response?.text()).toContain("window.captcha");
});

test("resolves inline package migrations for the requested database", () => {
  const migrations = resolvePackageMigrations(
    [
      { id: "default-schema", source: "-- +up\nCREATE TABLE one(id INTEGER);" },
      {
        id: "analytics-schema",
        database: "analytics",
        source: "-- +up\nCREATE TABLE events(id INTEGER);",
      },
    ],
    "analytics",
  );
  expect(migrations).toHaveLength(1);
  expect(migrations[0]?.name).toBe("analytics-schema");
  expect(migrations[0]?.up).toContain("CREATE TABLE events");
});

import { collectScripts } from "../src/runtime.ts";

test("collectScripts automatically adds a referenced package runtime once", () => {
  const scripts = collectScripts(
    '<main><div data-wrnexus-runtime="captcha"></div><div data-wrnexus-runtime="captcha"></div></main>',
    [{ id: "captcha", source: "window.captcha = true", type: "script" }],
  );
  expect(
    scripts.filter(
      (script) => typeof script !== "string" && script.src === "/__wrnexus/assets/captcha.js",
    ),
  ).toHaveLength(1);
});

test("collectScripts omits client navigation in document mode", () => {
  const scripts = collectScripts("<main>Server rendered</main>", [], {
    mode: "document",
  });

  expect(scripts).not.toContain("/__wrnexus/nav.js");
});

test("collectScripts ships zero framework JavaScript for static markup by default", () => {
  expect(collectScripts('<main><a href="/about">About</a></main>')).toEqual([]);
});

test("collectScripts adds navigation in explicit client mode", () => {
  expect(collectScripts("<main>Server rendered</main>", [], { mode: "client" })).toEqual([
    "/__wrnexus/nav.js",
  ]);
});

test("collectScripts auto-adds navigation when a page already needs a browser runtime", () => {
  expect(collectScripts('<button data-scope="{}">Count</button>')).toEqual([
    "/__wrnexus/nav.js",
    "/__wrnexus/reactive.js",
  ]);
});
