<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
'use strict';

function send_message_to_worker_and_wait_for_response(worker, message) {
  return new Promise(resolve => {
    // Use a dedicated channel for every request to avoid race conditions on
    // concurrent requests.
    const channel = new MessageChannel();
    worker.postMessage(channel.port1, [channel.port1]);

    let messageReceived = false;
    channel.port2.onmessage = event => {
      assert_false(messageReceived, 'Already received response for ' + message);
      messageReceived = true;
      resolve(event.data);
    };
    channel.port2.postMessage(message);
  });
}

async function ensure_install_event_fired(worker) {
  const response = await send_message_to_worker_and_wait_for_response(worker, 'awaitInstallEvent');
  assert_equals('installEventFired', response);
  assert_equals('installing', worker.state, 'Expected worker to be installing.');
}

async function finish_install(worker) {
  await ensure_install_event_fired(worker);
  const response = await send_message_to_worker_and_wait_for_response(worker, 'finishInstall');
  assert_equals('installFinished', response);
}

async function activate_service_worker(t, worker) {
  await finish_install(worker);
  // By waiting for both states at the same time, the test fails
  // quickly if the installation fails, avoiding a timeout.
  await Promise.race([wait_for_state(t, worker, 'activated'),
                      wait_for_state(t, worker, 'redundant')]);
  assert_equals('activated', worker.state, 'Service worker should be activated.');
}

async function update_within_service_worker(worker) {
  // This function returns a Promise that resolves when update()
  // has been called but is not necessarily finished yet.
  // Call finish() on the returned object to wait for update() settle.
  const port = await send_message_to_worker_and_wait_for_response(worker, 'callUpdate');
  let messageReceived = false;
  return {
    finish: () => {
      return new Promise(resolve => {
        port.onmessage = event => {
          assert_false(messageReceived, 'Update already finished.');
          messageReceived = true;
          resolve(event.data);
        };
      });
    },
  };
}

async function update_from_client_and_await_installing_version(test, registration) {
  const updatefound = wait_for_update(test, registration);
  registration.update();
  await updatefound;
  return registration.installing;
}

async function spin_up_service_worker(test) {
  const script = 'resources/update-during-installation-worker.py';
  const scope = 'resources/blank.html';

  const registration = await service_worker_unregister_and_register(test, script, scope);
  test.add_cleanup(async () => {
    if (registration.installing) {
      // If there is an installing worker, we need to finish installing it.
      // Otherwise, the tests fails with an timeout because unregister() blocks
      // until the install-event-handler finishes.
      const worker = registration.installing;
      await send_message_to_worker_and_wait_for_response(worker, 'awaitInstallEvent');
      await send_message_to_worker_and_wait_for_response(worker, 'finishInstall');
    }
    return registration.unregister();
  });

  return registration;
}

promise_test(async t => {
  const registration = await spin_up_service_worker(t);
  const worker = registration.installing;
  await ensure_install_event_fired(worker);

  const result = registration.update();
  await activate_service_worker(t, worker);
  return result;
}, 'ServiceWorkerRegistration.update() from client succeeds while installing service worker.');

promise_test(async t => {
  const registration = await spin_up_service_worker(t);
  const worker = registration.installing;
  await ensure_install_event_fired(worker);

  // Add event listener to fail the test if update() succeeds.
  const updatefound = t.step_func(async () => {
    registration.removeEventListener('updatefound', updatefound);
    // Activate new worker so non-compliant browsers don't fail with timeout.
    await activate_service_worker(t, registration.installing);
    assert_unreached("update() should have failed");
  });
  registration.addEventListener('updatefound', updatefound);

  const update = await update_within_service_worker(worker);
  // Activate worker to ensure update() finishes and the test doesn't timeout
  // in non-compliant browsers.
  await activate_service_worker(t, worker);

  const response = await update.finish();
  assert_false(response.success, 'update() should have failed.');
  assert_equals('InvalidStateError', response.exception, 'update() should have thrown InvalidStateError.');
}, 'ServiceWorkerRegistration.update() from installing service worker throws.');

promise_test(async t => {
  const registration = await spin_up_service_worker(t);
  const worker1 = registration.installing;
  await activate_service_worker(t, worker1);

  const worker2 = await update_from_client_and_await_installing_version(t, registration);
  await ensure_install_event_fired(worker2);

  const update = await update_within_service_worker(worker1);
  // Activate the new version so that update() finishes and the test doesn't timeout.
  await activate_service_worker(t, worker2);
  const response = await update.finish();
  assert_true(response.success, 'update() from active service worker should have succeeded.');
}, 'ServiceWorkerRegistration.update() from active service worker succeeds while installing service worker.');
</script>
