<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
const worker = 'resources/fetch-event-within-sw-worker.js';

function wait(ms) {
  return new Promise(r => setTimeout(r, ms));
}

function reset() {
  for (const iframe of [...document.querySelectorAll('.test-iframe')]) {
    iframe.remove();
  }
  return navigator.serviceWorker.getRegistrations().then(registrations => {
    return Promise.all(registrations.map(r => r.unregister()));
  }).then(() => caches.keys()).then(cacheKeys => {
    return Promise.all(cacheKeys.map(c => caches.delete(c)));
  });
}

add_completion_callback(reset);

function regReady(reg) {
  return new Promise((resolve, reject) => {
    if (reg.active) {
      resolve();
      return;
    }
    const nextWorker = reg.waiting || reg.installing;

    nextWorker.addEventListener('statechange', () => {
      if (nextWorker.state == 'redundant') {
        reject(Error(`Service worker failed to install`));
        return;
      }
      if (nextWorker.state == 'activated') {
        resolve();
      }
    });
  });
}

function getCookies() {
  return new Map(
    document.cookie
      .split(/;/g)
      .map(c => c.trim().split('=').map(s => s.trim()))
  );
}

function registerSwAndOpenFrame() {
  return reset().then(() => navigator.serviceWorker.register(worker, {scope: 'resources/'}))
    .then(reg => regReady(reg))
    .then(() => with_iframe('resources/simple.html'));
}

function raceBroadcastAndCookie(channel, cookie) {
  const initialCookie = getCookies().get(cookie);
  let done = false;

  return Promise.race([
    new Promise(resolve => {
      const bc = new BroadcastChannel(channel);
      bc.onmessage = () => {
        bc.close();
        resolve('broadcast');
      };
    }),
    (function checkCookie() {
      // Stop polling if the broadcast channel won
      if (done == true) return;
      if (getCookies().get(cookie) != initialCookie) return 'cookie';

      return wait(200).then(checkCookie);
    }())
  ]).then(val => {
    done = true;
    return val;
  });
}

promise_test(() => {
  return Notification.requestPermission().then(permission => {
    if (permission != "granted") {
      throw Error('You must allow notifications for this origin before running this test.');
    }
    return registerSwAndOpenFrame();
  }).then(iframe => {
    return Promise.resolve().then(() => {
      // In this test, the service worker will ping the 'icon-request' channel
      // if it intercepts a request for 'notification_icon.py'. If the request
      // reaches the server it sets the 'notification' cookie to the value given
      // in the URL. "raceBroadcastAndCookie" monitors both and returns which
      // happens first.
      const race = raceBroadcastAndCookie('icon-request', 'notification');
      const notification = new iframe.contentWindow.Notification('test', {
        icon: `notification_icon.py?set-cookie-notification=${Math.random()}`
      });
      notification.close();

      return race.then(winner => {
        assert_equals(winner, 'broadcast', 'The service worker intercepted the from-window notification icon request');
      });
    }).then(() => {
      // Similar race to above, but this time the service worker requests the
      // notification.
      const race = raceBroadcastAndCookie('icon-request', 'notification');
      iframe.contentWindow.fetch(`show-notification?set-cookie-notification=${Math.random()}`);

      return race.then(winner => {
        assert_equals(winner, 'broadcast', 'The service worker intercepted the from-service-worker notification icon request');
      });
    })
  });
}, `Notification requests intercepted both from window and SW`);

</script>
</body>
