// META: script=/resources/testharness.js
// META: script=/resources/testharnessreport.js
// META: script=resources/nfc-helpers.js

// NDEFReader.makeReadOnly method
// https://w3c.github.io/web-nfc/#dom-ndefreader-makereadonly

'use strict';

const invalid_signals = ['string', 123, {}, true, Symbol(), () => {}, self];

nfc_test(async t => {
  await test_driver.set_permission({name: 'nfc'}, 'denied', false);
  const ndef = new NDEFReader();
  await promise_rejects_dom(t, 'NotAllowedError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail if user permission is not granted.');

// We do not provide NFC mock here to simulate that there has no available
// implementation for NFC Mojo interface.
nfc_test(async (t, mockNFC) => {
  mockNFC.simulateClosedPipe();
  const ndef = new NDEFReader();
  await promise_rejects_dom(t, 'NotSupportedError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail if no implementation for NFC Mojo interface is available.');

nfc_test(async (t, mockNFC) => {
  const ndef = new NDEFReader();
  const controller = new AbortController();

  // Make sure makeReadOnly is pending
  mockNFC.setPendingMakeReadOnlyCompleted(false);
  const p = ndef.makeReadOnly({signal: controller.signal});
  const rejected = promise_rejects_dom(t, 'AbortError', p);
  let callback_called = false;
  await new Promise(resolve => {
    t.step_timeout(() => {
      callback_called = true;
      controller.abort();
      resolve();
    }, 10);
  });
  await rejected;
  assert_true(callback_called, 'timeout should have caused the abort');
}, 'NDEFReader.makeReadOnly should fail if request is aborted before makeReadOnly happends.');

nfc_test(async t => {
  const ndef = new NDEFReader();
  const controller = new AbortController();
  assert_false(controller.signal.aborted);
  controller.abort();
  assert_true(controller.signal.aborted);
  await promise_rejects_dom(
      t, 'AbortError', ndef.makeReadOnly({signal: controller.signal}));
}, 'NDEFReader.makeReadOnly should fail if signal is already aborted.');

nfc_test(async t => {
  const ndef = new NDEFReader();
  const promises = [];
  invalid_signals.forEach(invalid_signal => {
    promises.push(promise_rejects_js(
        t, TypeError, ndef.makeReadOnly({signal: invalid_signal})));
  });
  await Promise.all(promises);
}, 'NDEFReader.write should fail if signal is not an AbortSignal.');

nfc_test(async (t, mockNFC) => {
  const ndef1 = new NDEFReader();
  const ndef2 = new NDEFReader();
  const controller = new AbortController();
  const p1 = ndef1.makeReadOnly({signal: controller.signal});

  // Even though makeReadOnly request is grantable,
  // this abort should be processed synchronously.
  controller.abort();
  await promise_rejects_dom(t, 'AbortError', p1);

  await ndef2.makeReadOnly();
}, 'Synchronously signaled abort.');

nfc_test(async (t, mockNFC) => {
  const ndef = new NDEFReader();
  mockNFC.setHWStatus(NFCHWStatus.DISABLED);
  await promise_rejects_dom(t, 'NotReadableError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail when NFC HW is disabled.');

nfc_test(async (t, mockNFC) => {
  const ndef = new NDEFReader();
  mockNFC.setHWStatus(NFCHWStatus.NOT_SUPPORTED);
  await promise_rejects_dom(t, 'NotSupportedError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail when NFC HW is not supported.');

nfc_test(async () => {
  await new Promise((resolve, reject) => {
    const iframe = document.createElement('iframe');
    iframe.srcdoc = `<script>
                      window.onmessage = async (message) => {
                        if (message.data === "Ready") {
                          try {
                            const ndef = new NDEFReader();
                            await ndef.makeReadOnly();
                            parent.postMessage("Failure", "*");
                          } catch (error) {
                            if (error.name == "InvalidStateError") {
                              parent.postMessage("Success", "*");
                            } else {
                              parent.postMessage("Failure", "*");
                            }
                          }
                        }
                      };
                    </script>`;
    iframe.onload = () => iframe.contentWindow.postMessage('Ready', '*');
    document.body.appendChild(iframe);
    window.onmessage = message => {
      if (message.data == 'Success') {
        resolve();
      } else if (message.data == 'Failure') {
        reject();
      }
    }
  });
}, 'Test that WebNFC API is not accessible from iframe context.');

nfc_test(async () => {
  const ndef = new NDEFReader();
  await ndef.makeReadOnly();
}, 'NDEFReader.makeReadOnly should succeed when NFC HW is enabled');

nfc_test(async (t, mockNFC) => {
  const ndef1 = new NDEFReader();
  const ndef2 = new NDEFReader();

  // Make sure the first makeReadOnly will be pending.
  mockNFC.setPendingMakeReadOnlyCompleted(false);

  const p1 = ndef1.makeReadOnly();
  const p2 = ndef2.makeReadOnly();

  await promise_rejects_dom(t, 'AbortError', p1);
  await p2;
}, 'NDEFReader.makeReadOnly should replace all previously configured makeReadOnly operations.');

nfc_test(async () => {
  const ndef = new NDEFReader();

  const controller1 = new AbortController();
  await ndef.makeReadOnly({signal: controller1.signal});

  const controller2 = new AbortController();
  const promise = ndef.makeReadOnly({signal: controller2.signal});
  controller1.abort();
  await promise;
}, 'NDEFReader.makeReadOnly signals are independent.');

nfc_test(async (t, mockNFC) => {
  // Make sure the makeReadOnly will be pending in the mock.
  mockNFC.setPendingMakeReadOnlyCompleted(false);

  const ndef1 = new NDEFReader();
  const promise = ndef1.makeReadOnly();

  // Just to make sure the makeReadOnly() request has already reached to the
  // mock.
  const ndef2 = new NDEFReader();
  await ndef2.scan();

  mockNFC.simulateNonNDEFTagDiscovered();
  await promise_rejects_dom(t, 'NotSupportedError', promise);
}, 'NDEFReader.makeReadOnly should fail when the NFC device coming up does not expose \
NDEF technology.');

nfc_test(async (t, mockNFC) => {
  const ndef = new NDEFReader();
  mockNFC.simulateDataTransferFails();
  await promise_rejects_dom(t, 'NetworkError', ndef.makeReadOnly());
}, 'NDEFReader.makeReadOnly should fail with NetworkError when NFC data transfer fails.');
