// `integrityValue` indicates the 'integrity' attribute value at the time of
// #prepare-a-script.
//
// `integrityValueAfterPrepare` indicates how the 'integrity' attribute value
// is modified after #prepare-a-script:
// - `undefined` => not modified.
// - `null` => 'integrity' attribute is removed.
// - others => 'integrity' attribute value is set to that value.
//
// TODO: Make the arguments a dictionary for readability in the test files.
var SRIScriptTest = function(pass, name, src, integrityValue, crossoriginValue, nonce, integrityValueAfterPrepare) {
    this.pass = pass;
    this.name = "Script: " + name;
    this.src = src;
    this.integrityValue = integrityValue;
    this.crossoriginValue = crossoriginValue;
    this.nonce = nonce;
    this.integrityValueAfterPrepare = integrityValueAfterPrepare;
}

SRIScriptTest.prototype.execute = function() {
    var test = async_test(this.name);
    var e = document.createElement("script");
    e.src = this.src;
    if (this.integrityValue) {
      e.setAttribute("integrity", this.integrityValue);
    }
    if(this.crossoriginValue) {
        e.setAttribute("crossorigin", this.crossoriginValue);
    }
    if(this.nonce) {
      e.setAttribute("nonce", this.nonce);
    }
    if(this.pass) {
        e.addEventListener("load", function() {test.done()});
        e.addEventListener("error", function() {
            test.step(function(){ assert_unreached("Good load fired error handler.") })
        });
    } else {
       e.addEventListener("load", function() {
            test.step(function() { assert_unreached("Bad load succeeded.") })
        });
       e.addEventListener("error", function() {test.done()});
    }
    document.body.appendChild(e);

    if (this.integrityValueAfterPrepare === null) {
      e.removeAttribute("integrity");
    } else if (this.integrityValueAfterPrepare !== undefined) {
      e.setAttribute("integrity", this.integrityValueAfterPrepare);
    }
};

function set_extra_attributes(element, attrs) {
  // Apply the rest of the attributes, if any.
  for (const [attr_name, attr_val] of Object.entries(attrs)) {
    element[attr_name] = attr_val;
  }
}

function buildElementFromDestination(resource_url, destination, attrs) {
  // Assert: |destination| is a valid destination.
  let element;

  // The below switch is responsible for:
  //   1. Creating the correct subresource element
  //   2. Setting said element's href, src, or fetch-instigating property
  //      appropriately.
  switch (destination) {
    case "script":
      element = document.createElement(destination);
      set_extra_attributes(element, attrs);
      element.src = resource_url;
      break;
    case "style":
      element = document.createElement('link');
      set_extra_attributes(element, attrs);
      element.rel = 'stylesheet';
      element.href = resource_url;
      break;
    case "image":
      element = document.createElement('img');
      set_extra_attributes(element, attrs);
      element.src = resource_url;
      break;
    default:
      assert_unreached("INVALID DESTINATION");
  }

  return element;
}

// When using SRIPreloadTest, also include /preload/resources/preload_helper.js
// |number_of_requests| is used to ensure that preload requests are actually
// reused as expected.
const SRIPreloadTest = (preload_sri_success, subresource_sri_success, name,
                        number_of_requests, destination, resource_url,
                        link_attrs, subresource_attrs) => {
  const test = async_test(name);
  const link = document.createElement('link');

  // Early-fail in UAs that do not support `preload` links.
  test.step_func(() => {
    assert_true(link.relList.supports('preload'),
      "This test is automatically failing because the browser does not" +
      "support `preload` links.");
  })();

  // Build up the link.
  link.rel = 'preload';
  link.as = destination;
  link.href = resource_url;
  for (const [attr_name, attr_val] of Object.entries(link_attrs)) {
    link[attr_name] = attr_val; // This may override `rel` to modulepreload.
  }

  // Preload + subresource success and failure loading functions.
  const valid_preload_failed = test.step_func(() =>
    { assert_unreached("Valid preload fired error handler.") });
  const invalid_preload_succeeded = test.step_func(() =>
    { assert_unreached("Invalid preload load succeeded.") });
  const valid_subresource_failed = test.step_func(() =>
    { assert_unreached("Valid subresource fired error handler.") });
  const invalid_subresource_succeeded = test.step_func(() =>
    { assert_unreached("Invalid subresource load succeeded.") });
  const subresource_pass = test.step_func(() => {
    verifyNumberOfResourceTimingEntries(resource_url, number_of_requests);
    test.done();
  });
  const preload_pass = test.step_func(() => {
    const subresource_element = buildElementFromDestination(
      resource_url,
      destination,
      subresource_attrs
    );

    if (subresource_sri_success) {
      subresource_element.onload = subresource_pass;
      subresource_element.onerror = valid_subresource_failed;
    } else {
      subresource_element.onload = invalid_subresource_succeeded;
      subresource_element.onerror = subresource_pass;
    }

    document.body.append(subresource_element);
  });

  if (preload_sri_success) {
    link.onload = preload_pass;
    link.onerror = valid_preload_failed;
  } else {
    link.onload = invalid_preload_succeeded;
    link.onerror = preload_pass;
  }

  document.head.append(link);
}

// <link> tests
// Style tests must be done synchronously because they rely on the presence
// and absence of global style, which can affect later tests. Thus, instead
// of executing them one at a time, the style tests are implemented as a
// queue that builds up a list of tests, and then executes them one at a
// time.
var SRIStyleTest = function(queue, pass, name, attrs, customCallback, altPassValue) {
    this.pass = pass;
    this.name = "Style: " + name;
    this.customCallback = customCallback || function () {};
    this.attrs = attrs || {};
    this.passValue = altPassValue || "rgb(255, 255, 0)";

    this.test = async_test(this.name);

    this.queue = queue;
    this.queue.push(this);
}

SRIStyleTest.prototype.execute = function() {
  var that = this;
    var container = document.getElementById("container");
    while (container.hasChildNodes()) {
      container.removeChild(container.firstChild);
    }

    var test = this.test;

    var div = document.createElement("div");
    div.className = "testdiv";
    var e = document.createElement("link");

    // The link relation is guaranteed to not be "preload" or "modulepreload".
    this.attrs.rel = this.attrs.rel || "stylesheet";
    for (var key in this.attrs) {
        if (this.attrs.hasOwnProperty(key)) {
            e.setAttribute(key, this.attrs[key]);
        }
    }

    if(this.pass) {
        e.addEventListener("load", function() {
            test.step(function() {
                var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
                assert_equals(background, that.passValue);
                test.done();
            });
        });
        e.addEventListener("error", function() {
            test.step(function(){ assert_unreached("Good load fired error handler.") })
        });
    } else {
        e.addEventListener("load", function() {
             test.step(function() { assert_unreached("Bad load succeeded.") })
         });
        e.addEventListener("error", function() {
            test.step(function() {
                var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
                assert_not_equals(background, that.passValue);
                test.done();
            });
        });
    }
    container.appendChild(div);
    container.appendChild(e);
    this.customCallback(e, container);
};

