var state = "from_scope";
var resolvePromiseCallback;

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

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

  if (event.request.url.indexOf("update") >= 0) {
    state = "update";
  } else if (event.request.url.indexOf("wait") >= 0) {
    event.respondWith(new Promise(function(res, rej) {
      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.indexOf("release") >= 0) {
    state = "release";
    resolvePromise();
  }
}

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

onmessage = function(event) {
  var lastState = state;
  state = event.data;
  if (state === 'wait') {
    event.waitUntil(new Promise(function(res, rej) {
      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});
}

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"
  clients.matchAll().then(function(client) {
    if (client.length == 0) {
      dump("ERROR: no clients to send the response to.\n");
    }

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

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