'use strict';

// This polyfill library implements the WebUSB Test API as specified here:
// https://wicg.github.io/webusb/test/

(() => {

// These variables are logically members of the USBTest class but are defined
// here to hide them from being visible as fields of navigator.usb.test.
let internal = {
  intialized: false,

  deviceManager: null,
  deviceManagerInterceptor: null,
  deviceManagerCrossFrameProxy: null,

  chooser: null,
  chooserInterceptor: null,
  chooserCrossFrameProxy: null,
};

// Converts an ECMAScript String object to an instance of
// mojo.common.mojom.String16.
function mojoString16ToString(string16) {
  return String.fromCharCode.apply(null, string16.data);
}

// Converts an instance of mojo.common.mojom.String16 to an ECMAScript String.
function stringToMojoString16(string) {
  let array = new Array(string.length);
  for (var i = 0; i < string.length; ++i) {
    array[i] = string.charCodeAt(i);
  }
  return { data: array }
}

function fakeDeviceInitToDeviceInfo(guid, init) {
  let deviceInfo = {
    guid: guid + "",
    usbVersionMajor: init.usbVersionMajor,
    usbVersionMinor: init.usbVersionMinor,
    usbVersionSubminor: init.usbVersionSubminor,
    classCode: init.deviceClass,
    subclassCode: init.deviceSubclass,
    protocolCode: init.deviceProtocol,
    vendorId: init.vendorId,
    productId: init.productId,
    deviceVersionMajor: init.deviceVersionMajor,
    deviceVersionMinor: init.deviceVersionMinor,
    deviceVersionSubminor: init.deviceVersionSubminor,
    manufacturerName: stringToMojoString16(init.manufacturerName),
    productName: stringToMojoString16(init.productName),
    serialNumber: stringToMojoString16(init.serialNumber),
    activeConfiguration: init.activeConfigurationValue,
    configurations: []
  };
  init.configurations.forEach(config => {
    var configInfo = {
      configurationValue: config.configurationValue,
      configurationName: stringToMojoString16(config.configurationName),
      interfaces: []
    };
    config.interfaces.forEach(iface => {
      var interfaceInfo = {
        interfaceNumber: iface.interfaceNumber,
        alternates: []
      };
      iface.alternates.forEach(alternate => {
        var alternateInfo = {
          alternateSetting: alternate.alternateSetting,
          classCode: alternate.interfaceClass,
          subclassCode: alternate.interfaceSubclass,
          protocolCode: alternate.interfaceProtocol,
          interfaceName: stringToMojoString16(alternate.interfaceName),
          endpoints: []
        };
        alternate.endpoints.forEach(endpoint => {
          var endpointInfo = {
            endpointNumber: endpoint.endpointNumber,
            packetSize: endpoint.packetSize,
          };
          switch (endpoint.direction) {
          case "in":
            endpointInfo.direction = device.mojom.UsbTransferDirection.INBOUND;
            break;
          case "out":
            endpointInfo.direction = device.mojom.UsbTransferDirection.OUTBOUND;
            break;
          }
          switch (endpoint.type) {
          case "bulk":
            endpointInfo.type = device.mojom.UsbTransferType.BULK;
            break;
          case "interrupt":
            endpointInfo.type = device.mojom.UsbTransferType.INTERRUPT;
            break;
          case "isochronous":
            endpointInfo.type = device.mojom.UsbTransferType.ISOCHRONOUS;
            break;
          }
          alternateInfo.endpoints.push(endpointInfo);
        });
        interfaceInfo.alternates.push(alternateInfo);
      });
      configInfo.interfaces.push(interfaceInfo);
    });
    deviceInfo.configurations.push(configInfo);
  });
  return deviceInfo;
}

function convertMojoDeviceFilters(input) {
  let output = [];
  input.forEach(filter => {
    output.push(convertMojoDeviceFilter(filter));
  });
  return output;
}

function convertMojoDeviceFilter(input) {
  let output = {};
  if (input.hasVendorId)
    output.vendorId = input.vendorId;
  if (input.hasProductId)
    output.productId = input.productId;
  if (input.hasClassCode)
    output.classCode = input.classCode;
  if (input.hasSubclassCode)
    output.subclassCode = input.subclassCode;
  if (input.hasProtocolCode)
    output.protocolCode = input.protocolCode;
  if (input.serialNumber)
    output.serialNumber = mojoString16ToString(input.serialNumber);
  return output;
}

class FakeDevice {
  constructor(deviceInit) {
    this.info_ = deviceInit;
    this.opened_ = false;
    this.currentConfiguration_ = null;
    this.claimedInterfaces_ = new Map();
  }

  getConfiguration() {
    if (this.currentConfiguration_) {
      return Promise.resolve({
          value: this.currentConfiguration_.configurationValue });
    } else {
      return Promise.resolve({ value: 0 });
    }
  }

  open() {
    assert_false(this.opened_);
    this.opened_ = true;
    return Promise.resolve({ error: device.mojom.UsbOpenDeviceError.OK });
  }

  close() {
    assert_true(this.opened_);
    this.opened_ = false;
    return Promise.resolve();
  }

  setConfiguration(value) {
    assert_true(this.opened_);

    let selectedConfiguration = this.info_.configurations.find(
        configuration => configuration.configurationValue == value);
    // Blink should never request an invalid configuration.
    assert_not_equals(selectedConfiguration, undefined);
    this.currentConfiguration_ = selectedConfiguration;
    return Promise.resolve({ success: true });
  }

  claimInterface(interfaceNumber) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    assert_false(this.claimedInterfaces_.has(interfaceNumber),
                 'interface already claimed');

    // Blink should never request an invalid interface.
    assert_true(this.currentConfiguration_.interfaces.some(
            iface => iface.interfaceNumber == interfaceNumber));
    this.claimedInterfaces_.set(interfaceNumber, 0);
    return Promise.resolve({ success: true });
  }

  releaseInterface(interfaceNumber) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    assert_true(this.claimedInterfaces_.has(interfaceNumber));
    this.claimedInterfaces_.delete(interfaceNumber);
    return Promise.resolve({ success: true });
  }

  setInterfaceAlternateSetting(interfaceNumber, alternateSetting) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    assert_true(this.claimedInterfaces_.has(interfaceNumber));

    let iface = this.currentConfiguration_.interfaces.find(
        iface => iface.interfaceNumber == interfaceNumber);
    // Blink should never request an invalid interface or alternate.
    assert_false(iface == undefined);
    assert_true(iface.alternates.some(
        x => x.alternateSetting == alternateSetting));
    this.claimedInterfaces_.set(interfaceNumber, alternateSetting);
    return Promise.resolve({ success: true });
  }

  reset() {
    assert_true(this.opened_);
    return Promise.resolve({ success: true });
  }

  clearHalt(endpoint) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    // TODO(reillyg): Assert that endpoint is valid.
    return Promise.resolve({ success: true });
  }

  controlTransferIn(params, length, timeout) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    return Promise.resolve({
      status: device.mojom.UsbTransferStatus.OK,
      data: [length >> 8, length & 0xff, params.request, params.value >> 8,
             params.value & 0xff, params.index >> 8, params.index & 0xff]
    });
  }

  controlTransferOut(params, data, timeout) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    return Promise.resolve({
      status: device.mojom.UsbTransferStatus.OK,
      bytesWritten: data.byteLength
    });
  }

  genericTransferIn(endpointNumber, length, timeout) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    // TODO(reillyg): Assert that endpoint is valid.
    let data = new Array(length);
    for (let i = 0; i < length; ++i)
      data[i] = i & 0xff;
    return Promise.resolve({
      status: device.mojom.UsbTransferStatus.OK,
      data: data
    });
  }

  genericTransferOut(endpointNumber, data, timeout) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    // TODO(reillyg): Assert that endpoint is valid.
    return Promise.resolve({
      status: device.mojom.UsbTransferStatus.OK,
      bytesWritten: data.byteLength
    });
  }

  isochronousTransferIn(endpointNumber, packetLengths, timeout) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    // TODO(reillyg): Assert that endpoint is valid.
    let data = new Array(packetLengths.reduce((a, b) => a + b, 0));
    let dataOffset = 0;
    let packets = new Array(packetLengths.length);
    for (let i = 0; i < packetLengths.length; ++i) {
      for (let j = 0; j < packetLengths[i]; ++j)
        data[dataOffset++] = j & 0xff;
      packets[i] = {
        length: packetLengths[i],
        transferredLength: packetLengths[i],
        status: device.mojom.UsbTransferStatus.OK
      };
    }
    return Promise.resolve({ data: data, packets: packets });
  }

  isochronousTransferOut(endpointNumber, data, packetLengths, timeout) {
    assert_true(this.opened_);
    assert_false(this.currentConfiguration_ == null, 'device configured');
    // TODO(reillyg): Assert that endpoint is valid.
    let packets = new Array(packetLengths.length);
    for (let i = 0; i < packetLengths.length; ++i) {
      packets[i] = {
        length: packetLengths[i],
        transferredLength: packetLengths[i],
        status: device.mojom.UsbTransferStatus.OK
      };
    }
    return Promise.resolve({ packets: packets });
  }
}

class FakeDeviceManager {
  constructor() {
    this.bindingSet_ = new mojo.BindingSet(device.mojom.UsbDeviceManager);
    this.devices_ = new Map();
    this.devicesByGuid_ = new Map();
    this.client_ = null;
    this.nextGuid_ = 0;
  }

  addBinding(handle) {
    this.bindingSet_.addBinding(this, handle);
  }

  addDevice(fakeDevice, info) {
    let device = {
      fakeDevice: fakeDevice,
      guid: (this.nextGuid_++).toString(),
      info: info,
      bindingArray: []
    };
    this.devices_.set(fakeDevice, device);
    this.devicesByGuid_.set(device.guid, device);
    if (this.client_)
      this.client_.onDeviceAdded(fakeDeviceInitToDeviceInfo(device.guid, info));
  }

  removeDevice(fakeDevice) {
    let device = this.devices_.get(fakeDevice);
    if (!device)
      throw new Error('Cannot remove unknown device.');

    for (var binding of device.bindingArray)
      binding.close();
    this.devices_.delete(device.fakeDevice);
    this.devicesByGuid_.delete(device.guid);
    if (this.client_) {
      this.client_.onDeviceRemoved(
          fakeDeviceInitToDeviceInfo(device.guid, device.info));
    }
  }

  removeAllDevices() {
    this.devices_.forEach(device => {
      for (var binding of device.bindingArray)
        binding.close();
      this.client_.onDeviceRemoved(
          fakeDeviceInitToDeviceInfo(device.guid, device.info));
    });
    this.devices_.clear();
    this.devicesByGuid_.clear();
  }

  getDevices(options) {
    let devices = [];
    this.devices_.forEach(device => {
      devices.push(fakeDeviceInitToDeviceInfo(device.guid, device.info));
    });
    return Promise.resolve({ results: devices });
  }

  getDevice(guid, request) {
    let device = this.devicesByGuid_.get(guid);
    if (device) {
      let binding = new mojo.Binding(
          window.device.mojom.UsbDevice, new FakeDevice(device.info), request);
      binding.setConnectionErrorHandler(() => {
        if (device.fakeDevice.onclose)
          device.fakeDevice.onclose();
      });
      device.bindingArray.push(binding);
    } else {
      request.close();
    }
  }

  setClient(client) {
    this.client_ = client;
  }
}

class USBDeviceRequestEvent {
  constructor(deviceFilters, resolve) {
    this.filters = convertMojoDeviceFilters(deviceFilters);
    this.resolveFunc_ = resolve;
  }

  respondWith(value) {
    // Wait until |value| resolves (if it is a Promise). This function returns
    // no value.
    Promise.resolve(value).then(fakeDevice => {
      let device = internal.deviceManager.devices_.get(fakeDevice);
      let result = null;
      if (device) {
        result = fakeDeviceInitToDeviceInfo(device.guid, device.info);
      }
      this.resolveFunc_({ result: result });
    }, () => {
      this.resolveFunc_({ result: null });
    });
  }
}

class FakeChooserService {
  constructor() {
    this.bindingSet_ = new mojo.BindingSet(device.mojom.UsbChooserService);
  }

  addBinding(handle) {
    this.bindingSet_.addBinding(this, handle);
  }

  getPermission(deviceFilters) {
    return new Promise(resolve => {
      if (navigator.usb.test.onrequestdevice) {
        navigator.usb.test.onrequestdevice(
            new USBDeviceRequestEvent(deviceFilters, resolve));
      } else {
        resolve({ result: null });
      }
    });
  }
}

// Unlike FakeDevice this class is exported to callers of USBTest.addFakeDevice.
class FakeUSBDevice {
  constructor() {
    this.onclose = null;
  }

  disconnect() {
    setTimeout(() => internal.deviceManager.removeDevice(this), 0);
  }
}

// A helper for forwarding MojoHandle instances from one frame to another.
class CrossFrameHandleProxy {
  constructor(callback) {
    let {handle0, handle1} = Mojo.createMessagePipe();
    this.sender_ = handle0;
    this.receiver_ = handle1;
    this.receiver_.watch({readable: true}, () => {
      let message = this.receiver_.readMessage();
      assert_equals(message.buffer.byteLength, 0);
      assert_equals(message.handles.length, 1);
      callback(message.handles[0]);
    });
  }

  forwardHandle(handle) {
    this.sender_.writeMessage(new ArrayBuffer, [handle]);
  }
}

class USBTest {
  constructor() {
    this.onrequestdevice = undefined;
  }

  async initialize() {
    if (internal.initialized)
      return;

    internal.deviceManager = new FakeDeviceManager();
    internal.deviceManagerInterceptor =
        new MojoInterfaceInterceptor(device.mojom.UsbDeviceManager.name);
    internal.deviceManagerInterceptor.oninterfacerequest =
        e => internal.deviceManager.addBinding(e.handle);
    internal.deviceManagerInterceptor.start();
    internal.deviceManagerCrossFrameProxy = new CrossFrameHandleProxy(
        handle => internal.deviceManager.addBinding(handle));

    internal.chooser = new FakeChooserService();
    internal.chooserInterceptor =
        new MojoInterfaceInterceptor(device.mojom.UsbChooserService.name);
    internal.chooserInterceptor.oninterfacerequest =
        e => internal.chooser.addBinding(e.handle);
    internal.chooserInterceptor.start();
    internal.chooserCrossFrameProxy = new CrossFrameHandleProxy(
        handle => internal.chooser.addBinding(handle));

    // Wait for a call to GetDevices() to pass between the renderer and the
    // mock in order to establish that everything is set up.
    await navigator.usb.getDevices();
    internal.initialized = true;
  }

  async attachToWindow(otherWindow) {
    if (!internal.initialized)
      throw new Error('Call initialize() before attachToWindow().');

    otherWindow.deviceManagerInterceptor =
        new otherWindow.MojoInterfaceInterceptor(
            device.mojom.UsbDeviceManager.name);
    otherWindow.deviceManagerInterceptor.oninterfacerequest =
        e => internal.deviceManagerCrossFrameProxy.forwardHandle(e.handle);
    otherWindow.deviceManagerInterceptor.start();

    otherWindow.chooserInterceptor =
        new otherWindow.MojoInterfaceInterceptor(
            device.mojom.UsbChooserService.name);
    otherWindow.chooserInterceptor.oninterfacerequest =
        e => internal.chooserCrossFrameProxy.forwardHandle(e.handle);
    otherWindow.chooserInterceptor.start();

    // Wait for a call to GetDevices() to pass between the renderer and the
    // mock in order to establish that everything is set up.
    await otherWindow.navigator.usb.getDevices();
  }

  addFakeDevice(deviceInit) {
    if (!internal.initialized)
      throw new Error('Call initialize() before addFakeDevice().');

    // |addDevice| and |removeDevice| are called in a setTimeout callback so
    // that tests do not rely on the device being immediately available which
    // may not be true for all implementations of this test API.
    let fakeDevice = new FakeUSBDevice();
    setTimeout(
        () => internal.deviceManager.addDevice(fakeDevice, deviceInit), 0);
    return fakeDevice;
  }

  reset() {
    if (!internal.initialized)
      throw new Error('Call initialize() before reset().');

    // Reset the mocks in a setTimeout callback so that tests do not rely on
    // the fact that this polyfill can do this synchronously.
    return new Promise(resolve => {
      setTimeout(() => {
        internal.deviceManager.removeAllDevices();
        resolve();
      }, 0);
    });
  }
}

navigator.usb.test = new USBTest();

})();
