// Asserts that the given attributes are present in 'entry' and hold equal
// values.
const assert_all_equal_ = (entry, attributes) => {
  let first = attributes[0];
  attributes.slice(1).forEach(other => {
    assert_equals(entry[first], entry[other],
      `${first} should be equal to ${other}`);
  });
}

// Asserts that the given attributes are present in 'entry' and hold values
// that are sorted in the same order as given in 'attributes'.
const assert_ordered_ = (entry, attributes) => {
  let before = attributes[0];
  attributes.slice(1).forEach(after => {
    assert_greater_than_equal(entry[after], entry[before],
      `${after} should be greater than ${before}`);
    before = after;
  });
}

// Asserts that the given attributes are present in 'entry' and hold a value of
// 0.
const assert_zeroed_ = (entry, attributes) => {
  attributes.forEach(attribute => {
    assert_equals(entry[attribute], 0, `${attribute} should be 0`);
  });
}

// Asserts that the given attributes are present in 'entry' and hold a value of
// 0 or more.
const assert_not_negative_ = (entry, attributes) => {
  attributes.forEach(attribute => {
    assert_greater_than_equal(entry[attribute], 0,
      `${attribute} should be greater than or equal to 0`);
  });
}

// Asserts that the given attributes are present in 'entry' and hold a value
// greater than 0.
const assert_positive_ = (entry, attributes) => {
  attributes.forEach(attribute => {
    assert_greater_than(entry[attribute], 0,
      `${attribute} should be greater than 0`);
  });
}

const invariants = {
  // Asserts that attributes of the given PerformanceResourceTiming entry match
  // what the spec dictates for any resource fetched over HTTP without
  // redirects but passing the Timing-Allow-Origin checks.
  assert_tao_pass_no_redirect_http: entry => {
    assert_ordered_(entry, [
      "fetchStart",
      "domainLookupStart",
      "domainLookupEnd",
      "connectStart",
      "connectEnd",
      "requestStart",
      "responseStart",
      "responseEnd",
    ]);

    assert_zeroed_(entry, [
      "workerStart",
      "secureConnectionStart",
      "redirectStart",
      "redirectEnd",
    ]);

    assert_not_negative_(entry, [
      "duration",
    ]);

    assert_positive_(entry, [
      "fetchStart",
      "transferSize",
      "encodedBodySize",
      "decodedBodySize",
    ]);
  },

  // Like assert_tao_pass_no_redirect_http but for resources fetched over HTTPS
  assert_tao_pass_no_redirect_https: entry => {
    assert_ordered_(entry, [
      "fetchStart",
      "domainLookupStart",
      "domainLookupEnd",
      "secureConnectionStart",
      "connectStart",
      "connectEnd",
      "requestStart",
      "responseStart",
      "responseEnd",
    ]);

    assert_zeroed_(entry, [
      "workerStart",
      "redirectStart",
      "redirectEnd",
    ]);

    assert_not_negative_(entry, [
      "duration",
    ]);

    assert_positive_(entry, [
      "fetchStart",
      "transferSize",
      "encodedBodySize",
      "decodedBodySize",
    ]);
  },

  // Like assert_tao_pass_no_redirect_http but, since the resource's bytes
  // won't be retransmitted, the encoded and decoded sizes must be zero.
  assert_tao_pass_304_not_modified_http: entry => {
    assert_ordered_(entry, [
      "fetchStart",
      "domainLookupStart",
      "domainLookupEnd",
      "connectStart",
      "connectEnd",
      "requestStart",
      "responseStart",
      "responseEnd",
    ]);

    assert_zeroed_(entry, [
      "workerStart",
      "secureConnectionStart",
      "redirectStart",
      "redirectEnd",
      "encodedBodySize",
      "decodedBodySize",
    ]);

    assert_not_negative_(entry, [
      "duration",
    ]);

    assert_positive_(entry, [
      "fetchStart",
      "transferSize",
    ]);
  },

  // Like assert_tao_pass_304_not_modified_http but for resources fetched over
  // HTTPS.
  assert_tao_pass_304_not_modified_https: entry => {
    assert_ordered_(entry, [
      "fetchStart",
      "domainLookupStart",
      "domainLookupEnd",
      "secureConnectionStart",
      "connectStart",
      "connectEnd",
      "requestStart",
      "responseStart",
      "responseEnd",
    ]);

    assert_zeroed_(entry, [
      "workerStart",
      "redirectStart",
      "redirectEnd",
      "encodedBodySize",
      "decodedBodySize",
    ]);

    assert_not_negative_(entry, [
      "duration",
    ]);

    assert_positive_(entry, [
      "fetchStart",
      "transferSize",
    ]);
  },

  // Asserts that attributes of the given PerformanceResourceTiming entry match
  // what the spec dictates for any resource subsequently fetched over a
  // persistent connection. When this happens, we expect that certain
  // attributes describing transport layer behaviour will be equal.
  assert_connection_reused: entry => {
    assert_all_equal_(entry, [
      "fetchStart",
      "connectStart",
      "connectEnd",
      "domainLookupStart",
      "domainLookupEnd",
    ]);
  },

  // Asserts that attributes of the given PerformanceResourceTiming entry match
  // what the spec dictates for any resource fetched over HTTP through an HTTP
  // redirect.
  assert_same_origin_redirected_resource: entry => {
    assert_positive_(entry, [
      "redirectStart",
    ]);

    assert_equals(entry.redirectStart, entry.startTime,
      "redirectStart should be equal to startTime");

    assert_ordered_(entry, [
      "redirectStart",
      "redirectEnd",
      "fetchStart",
      "domainLookupStart",
      "domainLookupEnd",
      "connectStart",
    ]);
  },

  // Asserts that attributes of the given PerformanceResourceTiming entry match
  // what the spec dictates for any resource fetched over HTTPS through a
  // cross-origin redirect.
  // (e.g. GET http://remote.com/foo => 302 Location: https://remote.com/foo)
  assert_cross_origin_redirected_resource: entry => {
    assert_zeroed_(entry, [
      "redirectStart",
      "redirectEnd",
      "domainLookupStart",
      "domainLookupEnd",
      "connectStart",
      "connectEnd",
      "secureConnectionStart",
      "requestStart",
      "responseStart",
    ]);

    assert_positive_(entry, [
      "fetchStart",
      "responseEnd",
    ]);

    assert_ordered_(entry, [
      "fetchStart",
      "responseEnd",
    ]);
  },

  // Asserts that attributes of the given PerformanceResourceTiming entry match
  // what the spec dictates for a resource fetched over HTTPS through a
  // TAO enabled cross-origin redirect.
  assert_tao_enabled_cross_origin_redirected_resource: entry => {
    assert_positive_(entry, [
      "redirectStart",
    ]);
    assert_ordered_(entry, [
      "redirectStart",
      "redirectEnd",
      "fetchStart",
      "domainLookupStart",
      "domainLookupEnd",
      "connectStart",
      "secureConnectionStart",
      "connectEnd",
      "requestStart",
      "responseStart",
      "responseEnd",
    ]);
  },

  assert_same_origin_redirected_from_cross_origin_resource: entry => {
    assert_zeroed_(entry, [
      "workerStart",
      "redirectStart",
      "redirectEnd",
      "domainLookupStart",
      "domainLookupEnd",
      "connectStart",
      "connectEnd",
      "secureConnectionStart",
      "requestStart",
      "responseStart",
      "transferSize",
      "encodedBodySize",
      "decodedBodySize",
    ]);

    assert_ordered_(entry, [
      "fetchStart",
      "responseEnd",
    ]);

    assert_equals(entry.fetchStart, entry.startTime,
      "fetchStart must equal startTime");
  },

  assert_tao_failure_resource: entry => {
    assert_equals(entry.entryType, "resource", "entryType must always be 'resource'");

    assert_positive_(entry, [
      "startTime",
      "duration",
    ]);

    assert_zeroed_(entry, [
      "redirectStart",
      "redirectEnd",
      "domainLookupStart",
      "domainLookupEnd",
      "connectStart",
      "connectEnd",
      "secureConnectionStart",
      "requestStart",
      "responseStart",
      "transferSize",
      "encodedBodySize",
      "decodedBodySize",
    ]);
  }

};

const attribute_test_internal = (loader, path, validator, run_test, test_label) => {
  promise_test(
    async () => {
      let loaded_entry = new Promise((resolve, reject) => {
        new PerformanceObserver((entry_list, self) => {
          try {
            const name_matches = entry_list.getEntries().forEach(entry => {
              if (entry.name.includes(path)) {
                resolve(entry);
              }
            });
          } catch(e) {
            // By surfacing exceptions through the Promise interface, tests can
            // fail fast with a useful message instead of timing out.
            reject(e);
          }
        }).observe({"type": "resource"});
      });

      await loader(path, validator);
      const entry = await(loaded_entry);
      run_test(entry);
  }, test_label);
};

// Given a resource-loader, a path (a relative path or absolute URL), and a
// PerformanceResourceTiming test, applies the loader to the resource path
// and tests the resulting PerformanceResourceTiming entry.
const attribute_test = (loader, path, run_test, test_label) => {
  attribute_test_internal(loader, path, () => {}, run_test, test_label);
};

// Similar to attribute test, but on top of that, validates the added element,
// to ensure the test does what it intends to do.
const attribute_test_with_validator = (loader, path, validator, run_test, test_label) => {
  attribute_test_internal(loader, path, validator, run_test, test_label);
};
