// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
// META: script=resources/helpers.js
'use strict';

// Verifies that |func|, when invoked, throws a TypeError exception.
async function expectTypeError(func) {
  try {
    await func();
  } catch (e) {
    assert_equals(e.name, 'TypeError');
    return;
  }

  assert_unreached('expected a TypeError, but none was thrown');
}

promise_test(async () => {
  try {
    await navigator.contacts.select(['name']);
    assert_unreached('expected a SecurityError, but none was thrown');
  } catch (e) {
    assert_equals(e.name, 'SecurityError');
  }
}, 'The Contact API requires a user gesture')

contactsTestWithUserActivation(async (test, setSelectedContacts) => {
  // At least one property must be provided.
  await expectTypeError(() => navigator.contacts.select());
  await expectTypeError(() => navigator.contacts.select([]));

  // Per WebIDL parsing, no invalid values may be provided.
  await expectTypeError(() =>
      navigator.contacts.select(['']));
  await expectTypeError(() =>
      navigator.contacts.select(['foo']));
  await expectTypeError(() =>
      navigator.contacts.select(['name', 'photo']));

}, 'The Contact API requires valid properties to be provided');

contactsTestWithUserActivation(async (test, setSelectedContacts) => {
  // Returns a NULL result, indicating that no results are available.
  setSelectedContacts(null);

  await expectTypeError(() => navigator.contacts.select(['name']));

}, 'The Contact API can fail when the selector cannot be opened');

contactsTestWithUserActivation(async (test, setSelectedContacts) => {
  setSelectedContacts([]);

  const properties = await navigator.contacts.getProperties();
  assert_true(properties.length > 0);

  // Requesting the available properties should not fail.
  await navigator.contacts.select(properties);

}, 'Supported contact properties are exposed.');

contactsTestWithUserActivation(async (test, setSelectedContacts) => {
  const dwightAddress = {
    country: 'US',
    city: 'Scranton',
    addressLine: ['Schrute Farms'],
  };
  const michaelIcons = [new Blob('image binary data'.split(''), {type: 'image/test'})];

  // Returns two contacts with all information available.
  setSelectedContacts([
      { name: ['Dwight Schrute'], email: ['dwight@schrutefarmsbnb.com'], tel: ['000-0000'], address: [dwightAddress] },
      { name: ['Michael Scott', 'Prison Mike'], email: ['michael@dundermifflin.com'], icon: michaelIcons },
  ]);

  let results = await navigator.contacts.select(['name', 'email', 'icon', 'tel', 'address'], { multiple: true });
  assert_equals(results.length, 2);
  results = results.sort((c1, c2) => JSON.stringify(c1) < JSON.stringify(c2) ? -1 : 1);

  {
    const michael = results[0];

    assert_own_property(michael, 'name');
    assert_own_property(michael, 'email');
    assert_own_property(michael, 'tel');
    assert_own_property(michael, 'address');
    assert_own_property(michael, 'icon');

    assert_array_equals(michael.name, ['Michael Scott', 'Prison Mike']);
    assert_array_equals(michael.email, ['michael@dundermifflin.com']);
    assert_array_equals(michael.tel, []);
    assert_array_equals(michael.address, []);

    assert_equals(michael.icon.length, michaelIcons.length);
    assert_equals(michael.icon[0].type, michaelIcons[0].type);
    assert_equals(michael.icon[0].size, michaelIcons[0].size);
    assert_equals(await michael.icon[0].text(), await michaelIcons[0].text());
  }

  {
    const dwight = results[1];
    assert_own_property(dwight, 'name');
    assert_own_property(dwight, 'email');
    assert_own_property(dwight, 'tel');
    assert_own_property(dwight, 'address');
    assert_own_property(dwight, 'icon');

    assert_array_equals(dwight.name, ['Dwight Schrute']);
    assert_array_equals(dwight.email, ['dwight@schrutefarmsbnb.com']);
    assert_array_equals(dwight.tel, ['000-0000']);
    assert_array_equals(dwight.icon, []);

    assert_equals(dwight.address.length, 1);
    const selectedAddress = dwight.address[0];
    assert_object_equals({
      country: selectedAddress.country,
      city: selectedAddress.city,
      addressLine: selectedAddress.addressLine,
    }, dwightAddress);
  }
}, 'The Contact API correctly returns ContactInfo entries');

contactsTestWithUserActivation(async (test, setSelectedContacts) => {
  // Returns two contacts with all information available.
  setSelectedContacts([
      { name: ['Dwight Schrute'], email: ['dwight@schrutefarmsbnb.com'], tel: ['000-0000'] },
      { name: ['Michael Scott', 'Prison Mike'], email: ['michael@dundermifflin.com'] },
  ]);

  const results = await navigator.contacts.select(['name', 'email', 'tel']);
  assert_equals(results.length, 1);

}, 'Only one contact is returned if `multiple` is not set.');

contactsTestWithUserActivation(async (test, setSelectedContacts) => {
  // Returns partial information since no e-mail addresses are requested.
  setSelectedContacts([{ name: ['Creed'], email: ['creedthoughts@www.creedthoughts.gov.www'] }]);

  const results = await navigator.contacts.select(['name']);

  assert_equals(results.length, 1);

  {
    const creed = results[0];

    assert_array_equals(creed.name, ['Creed']);
    assert_equals(creed.email, undefined);
    assert_equals(creed.tel, undefined);
  }
}, 'The Contact API does not include fields that were not requested');

contactsTestWithUserActivation(async (test, setSelectedContacts) => {
  // Returns partial information since no e-mail addresses are requested.
  setSelectedContacts([{ name: ['Kelly'] }]);

  // First request should work.
  const promise1 = new Promise((resolve, reject) => {
    navigator.contacts.select(['name']).then(resolve)
                                       .catch(e => reject(e.message));
  });

  // Second request should fail (since the first one didn't complete yet).
  const promise2 = new Promise((resolve, reject) => {
    navigator.contacts.select(['name']).then(contacts => reject('This was supposed to fail'))
                                       .catch(e => resolve(e.name));
  });

  const results = await Promise.all([promise1, promise2]);
  const contacts = results[0];
  assert_equals(contacts.length, 1);
  const contact = contacts[0];
  assert_equals(contact.name[0], 'Kelly');
  assert_equals(results[1], 'InvalidStateError');

}, 'The Contact API cannot be used again until the first operation is complete.');

contactsTestWithUserActivation(async (test, setSelectedContacts) => {
  const iframe = document.createElement('iframe');
  document.body.appendChild(iframe);
  iframe.src = 'resources/non-main-frame-select.html';
  await new Promise(resolve => window.addEventListener('message', event => resolve(event.data)))
      .then(data => assert_equals(data.errorMsg, 'InvalidStateError'))
      .finally(() => iframe.remove())

}, 'Test contacts.select() throws an InvalidStateError in a sub-frame');
