const assert = require("assert");
const {
  injectDocumentCss,
  loadInjectedOverlayDocument,
  TRANSPARENT_WEBSITE_GUARD
} = require("../src/services/overlay-web-documents");
const { OBS_BROWSER_DEFAULT_CSS } = require("../src/services/obs-browser-defaults");

async function run() {
  const injected = injectDocumentCss(
    "<!doctype html><html><head><title>Alerts</title></head><body><div class=\"alert\">Hello</div></body></html>",
    "https://alerts.example/widgets/main/",
    ".alert { font-size: 64px; }"
  );
  assert(injected.includes('<base href="https://alerts.example/widgets/main/">'));
  assert(injected.includes('<style id="lumi-obs-browser-css">'));
  assert(injected.includes(OBS_BROWSER_DEFAULT_CSS));
  assert(injected.includes(TRANSPARENT_WEBSITE_GUARD));
  assert(injected.includes(".alert { font-size: 64px; }"));
  assert(injected.indexOf("lumi-obs-browser-css") > injected.indexOf("<title>Alerts</title>"), "website CSS must be appended after the website head content like OBS");
  assert(injected.includes('window.addEventListener("load",apply,{once:true})'), "website CSS must be re-applied when the main document finishes loading like OBS");
  assert(injected.includes("new MutationObserver(schedule)"), "late-loading alert apps must not be able to remove the transparency/CSS guard");
  assert(injected.includes('setProperty(\"background-color\",\"rgba(0, 0, 0, 0)\",\"important\")'));

  const opaqueAllowed = injectDocumentCss(
    "<html><head></head><body></body></html>",
    "https://alerts.example/widget",
    "body { background: white; }",
    { forceTransparentBackground: false }
  );
  assert(!opaqueAllowed.includes(TRANSPARENT_WEBSITE_GUARD));

  const withBase = injectDocumentCss(
    '<html><head><base href="../assets/"></head><body></body></html>',
    "https://alerts.example/widgets/main/",
    ""
  );
  assert(withBase.includes('<base href="https://alerts.example/widgets/assets/">'));
  assert.strictEqual((withBase.match(/<base\b/gi) || []).length, 1);

  let fetched = null;
  const loaded = await loadInjectedOverlayDocument("https://alerts.example/widget", "body { color: white; }", {
    resolveHost: async () => ["93.184.216.34"],
    fetchImpl: async (url, options) => {
      fetched = { url, options };
      return new Response("<html><head></head><body>Widget</body></html>", {
        status: 200,
        headers: { "Content-Type": "text/html; charset=utf-8" }
      });
    }
  });
  assert.strictEqual(fetched.url, "https://alerts.example/widget");
  assert.strictEqual(fetched.options.redirect, "manual");
  assert(loaded.html.includes(OBS_BROWSER_DEFAULT_CSS));
  assert(loaded.html.includes("body { color: white; }"));

  let privateFetchAttempted = false;
  await assert.rejects(
    loadInjectedOverlayDocument("http://127.0.0.1:8080/alerts", "", {
      fetchImpl: async () => {
        privateFetchAttempted = true;
        throw new Error("must not fetch");
      }
    }),
    /Private and local website addresses/
  );
  assert.strictEqual(privateFetchAttempted, false, "CSS injection must not turn Lumi into a private-network proxy");

  console.log("Overlay website document verification passed: OBS-default CSS injection, custom selectors, base URLs, bounded public fetching, and private-network blocking.");
}

run().catch((error) => {
  console.error(error);
  process.exit(1);
});
