"use strict";

const server = createHttpServer({ hosts: ["example.com"] });

const WIN = `<html><body>dummy page setting a same-site cookie</body></html>`;

// Small red image.
const IMG_BYTES = atob(
  "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" +
    "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
);

server.registerPathHandler("/same_site_cookies", (request, response) => {
  // avoid confusing cache behaviors
  response.setHeader("Cache-Control", "no-cache", false);

  if (request.queryString === "loadWin") {
    response.write(WIN);
    return;
  }

  // using startsWith and discard the math random
  if (request.queryString.startsWith("loadImage")) {
    response.setHeader(
      "Set-Cookie",
      "myKey=mySameSiteExtensionCookie; samesite=strict",
      true
    );
    response.setHeader("Content-Type", "image/png");
    response.write(IMG_BYTES);
    return;
  }

  if (request.queryString === "loadXHR") {
    let cookie = "noCookie";
    if (request.hasHeader("Cookie")) {
      cookie = request.getHeader("Cookie");
    }
    response.setHeader("Content-Type", "text/plain");
    response.write(cookie);
    return;
  }

  // We should never get here, but just in case return something unexpected.
  response.write("D'oh");
});

/* Description of the test:
 * (1) We load an image from mochi.test which sets a same site cookie
 * (2) We have the web extension perform an XHR request to mochi.test
 * (3) We verify the web-extension can access the same-site cookie
 */

add_task(async function test_webRequest_same_site_cookie_access() {
  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      permissions: ["http://example.com/*"],
      content_scripts: [
        {
          matches: ["http://example.com/*"],
          run_at: "document_end",
          js: ["content_script.js"],
        },
      ],
    },

    background() {
      browser.test.onMessage.addListener(msg => {
        if (msg === "verify-same-site-cookie-moz-extension") {
          let xhr = new XMLHttpRequest();
          try {
            xhr.open(
              "GET",
              "http://example.com/same_site_cookies?loadXHR",
              true
            );
            xhr.onload = function () {
              browser.test.assertEq(
                "myKey=mySameSiteExtensionCookie",
                xhr.responseText,
                "cookie should be accessible from moz-extension context"
              );
              browser.test.sendMessage("same-site-cookie-test-done");
            };
            xhr.onerror = function () {
              browser.test.fail("xhr onerror");
              browser.test.sendMessage("same-site-cookie-test-done");
            };
          } catch (e) {
            browser.test.fail("xhr failure: " + e);
          }
          xhr.send();
        }
      });
    },

    files: {
      "content_script.js": function () {
        let myImage = document.createElement("img");
        // Set the src via wrappedJSObject so the load is triggered with the
        // content page's principal rather than ours.
        myImage.wrappedJSObject.setAttribute(
          "src",
          "http://example.com/same_site_cookies?loadImage" + Math.random()
        );
        myImage.onload = function () {
          browser.test.log("image onload");
          browser.test.sendMessage("image-loaded-and-same-site-cookie-set");
        };
        myImage.onerror = function () {
          browser.test.log("image onerror");
        };
        document.body.appendChild(myImage);
      },
    },
  });

  await extension.startup();

  let contentPage = await ExtensionTestUtils.loadContentPage(
    "http://example.com/same_site_cookies?loadWin"
  );

  await extension.awaitMessage("image-loaded-and-same-site-cookie-set");

  extension.sendMessage("verify-same-site-cookie-moz-extension");
  await extension.awaitMessage("same-site-cookie-test-done");

  await contentPage.close();
  await extension.unload();
});
