var state = "from_scope";
var resolvePromiseCallback;

self.onfetch = function (event) {
  if (event.request.url.includes("lifetime_frame.html")) {
    event.respondWith(new Response("iframe_lifetime"));
    return;
  }

  var currentState = state;
  event.waitUntil(
    self.clients.matchAll().then(clients => {
      clients.forEach(client => {
        client.postMessage({ type: "fetch", state: currentState });
      });
    })
  );

  if (event.request.url.includes("update")) {
    state = "update";
  } else if (event.request.url.includes("wait")) {
    event.respondWith(
      new Promise(function (res) {
        if (resolvePromiseCallback) {
          dump("ERROR: service worker was already waiting on a promise.\n");
        }
        resolvePromiseCallback = function () {
          res(new Response("resolve_respondWithPromise"));
        };
      })
    );
    state = "wait";
  } else if (event.request.url.includes("release")) {
    state = "release";
    resolvePromise();
  }
};

function resolvePromise() {
  if (resolvePromiseCallback === undefined || resolvePromiseCallback == null) {
    dump("ERROR: wait promise was not set.\n");
    return;
  }
  resolvePromiseCallback();
  resolvePromiseCallback = null;
}

self.onmessage = function (event) {
  var lastState = state;
  state = event.data;
  if (state === "wait") {
    event.waitUntil(
      new Promise(function (res) {
        if (resolvePromiseCallback) {
          dump("ERROR: service worker was already waiting on a promise.\n");
        }
        resolvePromiseCallback = res;
      })
    );
  } else if (state === "release") {
    resolvePromise();
  }
  event.source.postMessage({ type: "message", state: lastState });
};

self.onpush = function (event) {
  var pushResolve;
  event.waitUntil(
    new Promise(function (resolve) {
      pushResolve = resolve;
    })
  );

  // FIXME(catalinb): push message carry no data. So we assume the only
  // push message we get is "wait"
  self.clients.matchAll().then(function (client) {
    if (!client.length) {
      dump("ERROR: no clients to send the response to.\n");
    }

    client[0].postMessage({ type: "push", state });

    state = "wait";
    if (resolvePromiseCallback) {
      dump("ERROR: service worker was already waiting on a promise.\n");
    } else {
      resolvePromiseCallback = pushResolve;
    }
  });
};
