// META: script=../../../service-workers/service-worker/resources/test-helpers.sub.js
// META: script=/common/utils.js
// META: script=/common/get-host-info.sub.js
// META: script=resources/utils.js

const { REMOTE_HOST } = get_host_info();
const BASE_SCOPE = 'resources/basic.html?';

async function cleanup() {
  for (const iframe of document.querySelectorAll('.test-iframe')) {
    iframe.parentNode.removeChild(iframe);
  }

  for (const reg of await navigator.serviceWorker.getRegistrations()) {
    await reg.unregister();
  }
}

async function setupRegistration(t, scope) {
  await cleanup();
  const reg = await navigator.serviceWorker.register('resources/range-sw.js', { scope });
  await wait_for_state(t, reg.installing, 'activated');
  return reg;
}

function awaitMessage(obj, id) {
  return new Promise(resolve => {
    obj.addEventListener('message', function listener(event) {
      if (event.data.id !== id) return;
      obj.removeEventListener('message', listener);
      resolve(event.data);
    });
  });
}

promise_test(async t => {
  const scope = BASE_SCOPE + Math.random();
  const reg = await setupRegistration(t, scope);
  const iframe = await with_iframe(scope);
  const w = iframe.contentWindow;

  // Trigger a cross-origin range request using media
  const url = new URL('long-wav.py?action=range-header-filter-test', w.location);
  url.hostname = REMOTE_HOST;
  appendAudio(w.document, url);

  // See rangeHeaderFilterTest in resources/range-sw.js
  await fetch_tests_from_worker(reg.active);
}, `Defer range header filter tests to service worker`);

promise_test(async t => {
  const scope = BASE_SCOPE + Math.random();
  const reg = await setupRegistration(t, scope);
  const iframe = await with_iframe(scope);
  const w = iframe.contentWindow;

  // Trigger a cross-origin range request using media
  const url = new URL('long-wav.py', w.location);
  url.searchParams.set('action', 'range-header-passthrough-test');
  url.searchParams.set('range-received-key', token());
  url.hostname = REMOTE_HOST;
  appendAudio(w.document, url);

  // See rangeHeaderPassthroughTest in resources/range-sw.js
  await fetch_tests_from_worker(reg.active);
}, `Defer range header passthrough tests to service worker`);

promise_test(async t => {
  const scope = BASE_SCOPE + Math.random();
  await setupRegistration(t, scope);
  const iframe = await with_iframe(scope);
  const w = iframe.contentWindow;
  const id = Math.random() + '';
  const storedRangeResponse = awaitMessage(w.navigator.serviceWorker, id);

  // Trigger a cross-origin range request using media
  const url = new URL('partial-script.py', w.location);
  url.searchParams.set('require-range', '1');
  url.searchParams.set('action', 'store-ranged-response');
  url.searchParams.set('id', id);
  url.hostname = REMOTE_HOST;

  appendAudio(w.document, url);

  await storedRangeResponse;

  // Fetching should reject
  const fetchPromise = w.fetch('?action=use-stored-ranged-response', { mode: 'no-cors' });
  promise_rejects(t, new TypeError(), fetchPromise);

  // Script loading should error too
  const loadScriptPromise = loadScript('?action=use-stored-ranged-response', { doc: w.document });
  promise_rejects(t, new Error(), loadScriptPromise);

  await loadScriptPromise.catch(() => {});

  assert_false(!!w.scriptExecuted, `Partial response shouldn't be executed`);
}, `Ranged response not allowed following no-cors ranged request`);

promise_test(async t => {
  const scope = BASE_SCOPE + Math.random();
  await setupRegistration(t, scope);
  const iframe = await with_iframe(scope);
  const w = iframe.contentWindow;
  const id = Math.random() + '';
  const storedRangeResponse = awaitMessage(w.navigator.serviceWorker, id);

  // Trigger a range request using media
  const url = new URL('partial-script.py', w.location);
  url.searchParams.set('require-range', '1');
  url.searchParams.set('action', 'store-ranged-response');
  url.searchParams.set('id', id);

  appendAudio(w.document, url);

  await storedRangeResponse;

  // This should not throw
  await w.fetch('?action=use-stored-ranged-response');

  // This shouldn't throw either
  await loadScript('?action=use-stored-ranged-response', { doc: w.document });

  assert_true(w.scriptExecuted, `Partial response should be executed`);
}, `Non-opaque ranged response executed`);

promise_test(async t => {
  const scope = BASE_SCOPE + Math.random();
  await setupRegistration(t, scope);
  const iframe = await with_iframe(scope);
  const w = iframe.contentWindow;
  const fetchId = Math.random() + '';
  const fetchBroadcast = awaitMessage(w.navigator.serviceWorker, fetchId);
  const audioId = Math.random() + '';
  const audioBroadcast = awaitMessage(w.navigator.serviceWorker, audioId);

  const url = new URL('long-wav.py', w.location);
  url.searchParams.set('action', 'broadcast-accept-encoding');
  url.searchParams.set('id', fetchId);

  await w.fetch(url, {
    headers: { Range: 'bytes=0-10' }
  });

  assert_equals((await fetchBroadcast).acceptEncoding, null, "Accept-Encoding should not be set for fetch");

  url.searchParams.set('id', audioId);
  appendAudio(w.document, url);

  assert_equals((await audioBroadcast).acceptEncoding, null, "Accept-Encoding should not be set for media");
}, `Accept-Encoding should not appear in a service worker`);
