let swOption = new URL(location.href).searchParams.get('sw');

if (swOption === 'fetch-handler-navigation-preload') {
  self.addEventListener('activate', event => {
    if (self.registration.navigationPreload) {
      event.waitUntil(self.registration.navigationPreload.enable());
    }
  });
}

if (swOption === 'race-fetch-handler' ||
  swOption === 'race-fetch-handler-to-fallback' ||
  swOption === 'race-fetch-handler-modify-url') {
  swOption = swOption.substring('race-'.length);
  self.addEventListener('install', event => {
    event.addRoutes([{
      condition: { urlPattern: { pathname: '/**/counting-executor.py' } },
      source: 'race-network-and-fetch-handler'
    }]);
  });
}

const interceptedRequests = [];

self.addEventListener('message', event => {
  if (event.data === 'getInterceptedRequests') {
    event.source.postMessage(interceptedRequests);
  }
});

if (swOption !== 'no-fetch-handler') {
  self.addEventListener('fetch', event => {

    // Intercept the prefetched and navigated URLs only (e.g. do not intercept
    // subresource requests related to `/common/dispatcher/dispatcher.js`).
    if (!event.request.url.includes('counting-executor.py')) {
      return;
    }

    const headers = {};
    event.request.headers.forEach((value, key) => {
      headers[key] = value;
    });
    const interceptedRequest = {
      request: {
        url: event.request.url,
        headers: headers,
      },
      clientId: event.clientId,
      resultingClientId: event.resultingClientId
    };
    interceptedRequests.push(interceptedRequest);

    if (swOption === 'fetch-handler') {
      event.respondWith(fetch(event.request));
    } else if (swOption === 'fetch-handler-synthetic') {
      const finalUrl = new URL(event.request.url).searchParams.get('location');
      if (finalUrl) {
        event.respondWith(Response.redirect(finalUrl));
      } else {
        // Fallback to the network.
      }
    } else if (swOption === 'fetch-handler-modify-url') {
      // The "Sec-Purpose: prefetch" header is dropped in fetch-handler-modify-*
      // cases in Step 33 of // https://fetch.spec.whatwg.org/#dom-request
      // because it's a https://fetch.spec.whatwg.org/#forbidden-request-header
      const url = new URL(event.request.url);
      url.searchParams.set('intercepted', 'true');
      event.respondWith(fetch(url, {headers: event.request.headers}));
    } else if (swOption === 'fetch-handler-modify-referrer') {
      event.respondWith(fetch(event.request,
          {referrer: new URL('/intercepted', location.href).href}));
    } else if (swOption === 'fetch-handler-navigation-preload') {
      event.respondWith((async () => {
        try {
          if (event.preloadResponse === 'undefined') {
            interceptedRequest.preloadResponse = 'undefined';
            return fetch(event.request);
          }
          const response = await event.preloadResponse;
          if (response) {
            interceptedRequest.preloadResponse = 'resolved';
            return response;
          } else {
            interceptedRequest.preloadResponse = 'resolved to undefined';
            return fetch(event.request);
          }
        } catch(e) {
          interceptedRequest.preloadResponse = 'rejected';
          throw e;
        }
      })());
    } else {
      // Do nothing to fallback to the network.
    }
  });
}
