<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/bluetooth-helpers.js"></script>
<script>
'use strict';

test(t => { assert_true(window.testRunner instanceof Object); t.done(); },
     'window.testRunner is required for the following tests.');

promise_test(() => {
  testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
  return requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]})
    .then(device => device.connectGATT())
    .then(gattServer => gattServer.getPrimaryService('generic_access'))
    .then(service => {
      testRunner.setBluetoothMockDataSet('EmptyAdapter');
      return assert_promise_rejects_with_message(
        service.getCharacteristic('gap.device_name'), {
          name: 'NetworkError',
          message: 'Bluetooth Device is no longer in range.'
        }, 'Device went out of range.');
    });
}, 'Device goes out of range. Reject with NetworkError.');

promise_test(() => {
  testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
  return requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]})
    .then(device => device.connectGATT())
    .then(gattService => gattService.getPrimaryService('generic_access'))
    .then(service => {
      testRunner.setBluetoothMockDataSet('MissingServiceGenericAccessAdapter');
      return assert_promise_rejects_with_message(
        service.getCharacteristic('gap.device_name'), {
          name: 'InvalidStateError',
          message: 'GATT Service no longer exists.'
        }, 'Service got removed.');
    });
}, 'Service is removed. Reject with InvalidStateError.');


promise_test(() => {
  testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
  return requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]})
    .then(device => device.connectGATT())
    .then(gattServer => gattServer.getPrimaryService('generic_access'))
    .then(service => Promise.all(
      [service.getCharacteristic(battery_level.alias),
       service.getCharacteristic(battery_level.name),
       service.getCharacteristic(battery_level.uuid)]))
    .then(characteristics => {
      characteristics.forEach(characteristic => {
        assert_equals(characteristic, null,
                      'Non existent characteristic should return null.');
      });
    });
}, 'Request for wrong characteristic. Should return null.');

promise_test(() => {
  testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
  return requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]})
    .then(device => device.connectGATT())
    .then(gattServer => gattServer.getPrimaryService('generic_access'))
    .then(service => Promise.all(
      [service.getCharacteristic(device_name.alias),
       service.getCharacteristic(device_name.name),
       service.getCharacteristic(device_name.uuid)]))
    .then(characteristics => {
      characteristics.forEach(characteristic => {
        assert_equals(
          characteristic.uuid, device_name.uuid,
          'Characteristic UUID should be the same as requested UUID.');
      });
    });
}, 'Request for characteristic. Should return right characteristic');

promise_test(() => {
  testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
  return requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]})
    .then(device => device.connectGATT())
    .then(gattServer => gattServer.getPrimaryService('generic_access'))
    .then(services => Promise.all(
      [services.getCharacteristic(device_name.alias),
       services.getCharacteristic(device_name.alias),
       services.getCharacteristic(device_name.name),
       services.getCharacteristic(device_name.name),
       services.getCharacteristic(device_name.uuid),
       services.getCharacteristic(device_name.uuid)]))
    .then(characteristics => {
      // TODO(ortuno): getCharacteristic should return the same object
      // if it was created earlier.
      // https://crbug.com/495270
      for (var i = 1; i < characteristics.length; i++) {
        assert_not_equals(
          characteristics[0], characteristics[i],
          'Should return the same characteristic as the first call.');
      }
    });
}, 'Calls to get the same characteristic should return the same object.');

promise_test(() => {
  testRunner.setBluetoothMockDataSet('GenericAccessAdapter');
  return requestDeviceWithKeyDown({filters: [{services: ['generic_access']}]})
    .then(device => device.connectGATT())
    .then(gattServer => gattServer.getPrimaryService('generic_access'))
    .then(service => {
      return assert_promise_rejects_with_message(
        service.getCharacteristic('wrong_name'), {
          name: 'SyntaxError',
          message: 'Failed to execute \'getCharacteristic\' on ' +
                   '\'BluetoothGATTService\': \Invalid Characteristic name: ' +
                   '\'wrong_name\'. ' +
                   'It must be a valid UUID alias (e.g. 0x1234), ' +
                   'UUID (lowercase hex characters e.g. ' +
                   '\'00001234-0000-1000-8000-00805f9b34fb\'), ' +
                   'or recognized standard name from ' +
                   'https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicsHome.aspx' +
                   ' e.g. \'aerobic_heart_rate_lower_limit\'.'
        }, 'Wrong Characteristic name passed.');
    });
}, 'Wrong Characteristic name. Reject with SyntaxError.');
</script>
