// Here's how waitForNotification works:
//
// - myTestFunction0()
//   - waitForNotification(myTestFunction1)
//     - requestAnimationFrame()
//   - Modify DOM in a way that should trigger an IntersectionObserver callback.
// - BeginFrame
//   - requestAnimationFrame handler runs
//     - Second requestAnimationFrame()
//   - Style, layout, paint
//   - IntersectionObserver generates new notifications
//     - Posts a task to deliver notifications
// - Task to deliver IntersectionObserver notifications runs
//   - IntersectionObserver callbacks run
// - Second requestAnimationFrameHandler runs
//     - step_timeout()
// - step_timeout handler runs
//   - myTestFunction1()
//     - [optional] waitForNotification(myTestFunction2)
//       - requestAnimationFrame()
//     - Verify newly-arrived IntersectionObserver notifications
//     - [optional] Modify DOM to trigger new notifications
//
// Ideally, it should be sufficient to use requestAnimationFrame followed
// by two step_timeouts, with the first step_timeout firing in between the
// requestAnimationFrame handler and the task to deliver notifications.
// However, the precise timing of requestAnimationFrame, the generation of
// a new display frame (when IntersectionObserver notifications are
// generated), and the delivery of these events varies between engines, making
// this tricky to test in a non-flaky way.
//
// In particular, in WebKit, requestAnimationFrame and the generation of
// a display frame are two separate tasks, so a step_timeout called within
// requestAnimationFrame can fire before a display frame is generated.
//
// In Gecko, on the other hand, requestAnimationFrame and the generation of
// a display frame are a single task, and IntersectionObserver notifications
// are generated during this task. However, the task posted to deliver these
// notifications can fire after the following requestAnimationFrame.
//
// This means that in general, by the time the second requestAnimationFrame
// handler runs, we know that IntersectionObservations have been generated,
// and that a task to deliver these notifications has been posted (though
// possibly not yet delivered). Then, by the time the step_timeout() handler
// runs, these notifications have been delivered.
//
// Since waitForNotification uses a double-rAF, it is now possible that
// IntersectionObservers may have generated more notifications than what is
// under test, but have not yet scheduled the new batch of notifications for
// delivery. As a result, observer.takeRecords should NOT be used in tests:
//
// - myTestFunction0()
//   - waitForNotification(myTestFunction1)
//     - requestAnimationFrame()
//   - Modify DOM in a way that should trigger an IntersectionObserver callback.
// - BeginFrame
//   - requestAnimationFrame handler runs
//     - Second requestAnimationFrame()
//   - Style, layout, paint
//   - IntersectionObserver generates a batch of notifications
//     - Posts a task to deliver notifications
// - Task to deliver IntersectionObserver notifications runs
//   - IntersectionObserver callbacks run
// - BeginFrame
//   - Second requestAnimationFrameHandler runs
//     - step_timeout()
//   - IntersectionObserver generates another batch of notifications
//     - Post task to deliver notifications
// - step_timeout handler runs
//   - myTestFunction1()
//     - At this point, observer.takeRecords will get the second batch of
//       notifications.
function waitForNotification(t, f) {
  requestAnimationFrame(function() {
    requestAnimationFrame(function() { t.step_timeout(f, 0); });
  });
}

// If you need to wait until the IntersectionObserver algorithm has a chance
// to run, but don't need to wait for delivery of the notifications...
function waitForFrame(t, f) {
  requestAnimationFrame(function() {
    t.step_timeout(f, 0);
  });
}

// The timing of when runTestCycle is called is important.  It should be
// called:
//
//   - Before or during the window load event, or
//   - Inside of a prior runTestCycle callback, *before* any assert_* methods
//     are called.
//
// Following these rules will ensure that the test suite will not abort before
// all test steps have run.
//
// If the 'delay' parameter to the IntersectionObserver constructor is used,
// tests will need to add the same delay to their runTestCycle invocations, to
// wait for notifications to be generated and delivered.
function runTestCycle(f, description, delay) {
  var cobalt_test_func = () => {
    f();
    window.testRunner.DoNonMeasuredLayout();
  }
  async_test(function(t) {
    if (delay) {
      step_timeout(() => {
        waitForNotification(t, t.step_func_done(cobalt_test_func));
      }, delay);
    } else {
      waitForNotification(t, t.step_func_done(cobalt_test_func));
    }
  }, description);
}

// Root bounds for a root with an overflow clip as defined by:
//   http://wicg.github.io/IntersectionObserver/#intersectionobserver-root-intersection-rectangle
function contentBounds(root) {
  var left = root.offsetLeft + root.clientLeft;
  var right = left + root.clientWidth;
  var top = root.offsetTop + root.clientTop;
  var bottom = top + root.clientHeight;
  return [left, right, top, bottom];
}

// Root bounds for a root without an overflow clip as defined by:
//   http://wicg.github.io/IntersectionObserver/#intersectionobserver-root-intersection-rectangle
function borderBoxBounds(root) {
  var left = root.offsetLeft;
  var right = left + root.offsetWidth;
  var top = root.offsetTop;
  var bottom = top + root.offsetHeight;
  return [left, right, top, bottom];
}

function clientBounds(element) {
  var rect = element.getBoundingClientRect();
  return [rect.left, rect.right, rect.top, rect.bottom];
}

function rectArea(rect) {
  return (rect.left - rect.right) * (rect.bottom - rect.top);
}

function checkRect(actual, expected, description, all) {
  if (!expected.length)
    return;
  assert_equals(actual.left | 0, expected[0] | 0, description + '.left');
  assert_equals(actual.right | 0, expected[1] | 0, description + '.right');
  assert_equals(actual.top | 0, expected[2] | 0, description + '.top');
  assert_equals(actual.bottom | 0, expected[3] | 0, description + '.bottom');
}

function checkLastEntry(entries, i, expected) {
  assert_equals(entries.length, i + 1, 'entries.length');
  if (expected) {
    checkRect(
        entries[i].boundingClientRect, expected.slice(0, 4),
        'entries[' + i + '].boundingClientRect', entries[i]);
    checkRect(
        entries[i].intersectionRect, expected.slice(4, 8),
        'entries[' + i + '].intersectionRect', entries[i]);
    /* TODO: Fix bug with rootBounds values. */
    // checkRect(
    //     entries[i].rootBounds, expected.slice(8, 12),
    //     'entries[' + i + '].rootBounds', entries[i]);
    if (expected.length > 12) {
      assert_equals(
          entries[i].isIntersecting, expected[12],
          'entries[' + i + '].isIntersecting');
    }
  }
}

function checkJsonEntry(actual, expected) {
  checkRect(
      actual.boundingClientRect, expected.boundingClientRect,
      'entry.boundingClientRect');
  checkRect(
      actual.intersectionRect, expected.intersectionRect,
      'entry.intersectionRect');
  if (actual.rootBounds == 'null')
    assert_equals(expected.rootBounds, 'null', 'rootBounds is null');
  else
    checkRect(actual.rootBounds, expected.rootBounds, 'entry.rootBounds');
  assert_equals(actual.isIntersecting, expected.isIntersecting);
  assert_equals(actual.target, expected.target);
}

function checkJsonEntries(actual, expected, description) {
  test(function() {
    assert_equals(actual.length, expected.length);
    for (var i = 0; i < actual.length; i++)
      checkJsonEntry(actual[i], expected[i]);
  }, description);
}

function checkIsIntersecting(entries, i, expected) {
  assert_equals(entries[i].isIntersecting, expected,
    'entries[' + i + '].target.isIntersecting equals ' + expected);
}
