// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <iostream>

#include <emscripten.h>
#include <libusb-1.0/libusb.h>

#include "tflite/queue.h"

#define LIBUSB_MAJOR 1
#define LIBUSB_MINOR 0
#define LIBUSB_MICRO 24
#define LIBUSB_NANO 0
#define LIBUSB_RC ""

// #define LIBUSB_ENABLE_LOG
#ifdef LIBUSB_ENABLE_LOG
#define LIBUSB_LOG(...)           \
  do {                            \
    fprintf(stdout, __VA_ARGS__); \
    fflush(stdout);               \
  } while (false)
#else  // LIBUSB_ENABLE_LOG
#define LIBUSB_LOG(...)
#endif  // LIBUSB_ENABLE_LOG

struct libusb_device {
  uint8_t bus_number;
  uint8_t port_number;
  struct libusb_context *ctx;
  struct libusb_device_descriptor descriptor;
};

struct libusb_context {
  Queue<libusb_transfer*> completed_transfers;
  libusb_device dev;
};

struct libusb_device_handle {
  struct libusb_device *dev;
};

static const struct libusb_version kVersion = {
  LIBUSB_MAJOR,
  LIBUSB_MINOR,
  LIBUSB_MICRO,
  LIBUSB_NANO,
  LIBUSB_RC,
  "http://libusb.info"
};

static int js_request_device(struct libusb_device *dev) {
  return MAIN_THREAD_EM_ASM_INT({
    return Asyncify.handleAsync(async () => {
      // Bus 001 Device 005: ID 1a6e:089a Global Unichip Corp.
      // Bus 002 Device 007: ID 18d1:9302 Google Inc.
      let options = {'filters': [{'vendorId': 0x18d1, 'productId': 0x9302}]};
      let devices = await navigator.usb.getDevices();
      if (!devices.length) {
        try {
          let device = await navigator.usb.requestDevice(options);
          devices = [device];
        } catch (error) {
          devices = []
        }
      }

      if (devices.length === 1) {
        let d = devices[0];
        _fill_device($0,
                   /*bcdUSB=*/(d.usbVersionMajor << 8) | d.usbVersionMinor,
                   /*bDeviceClass=*/d.deviceClass,
                   /*bDeviceSubClass=*/d.deviceSubClass,
                   /*bDeviceProtocol=*/d.deviceProtocol,
                   /*idVendor=*/d.vendorId,
                   /*idProduct=*/d.productId,
                   /*bcdDevice=*/(d.deviceVersionMajor << 8) | ((d.deviceVersionMinor << 4) | d.deviceVersionSubminor),
                   /*bNumConfigurations=*/d.configurations.length);
        this.libusb_device = devices[0];
        return 1;
      }
      return 0;
    });
  }, dev);
}

static int js_control_transfer(uint8_t bmRequestType, uint8_t bRequest,
                               uint16_t wValue, uint16_t wIndex, uint8_t *data,
                               uint16_t wLength, unsigned int timeout) {
  return MAIN_THREAD_EM_ASM_INT({
    return Asyncify.handleAsync(async () => {
      let bmRequestType = $0;
      let bRequest = $1;
      let wValue = $2;
      let wIndex = $3;
      let data = $4;
      let wLength = $5;
      let timeout = $6;

      let setup = {
        'requestType': ['standard', 'class', 'vendor'][(bmRequestType & 0x60) >> 5],
        'recipient': ['device', 'interface', 'endpoint', 'other'][(bmRequestType & 0x1f)],
        'request': bRequest,
        'value': wValue,
        'index': wIndex,
      };

      let dir_in = (bmRequestType & 0x80) == 0x80;
      if (dir_in) {
        let result = await this.libusb_device.controlTransferIn(setup, wLength);
        if (result.status != 'ok') {
          console.error('controlTransferIn', result);
          return 0;
        }

        let view = new Uint8Array(result.data.buffer);
        writeArrayToMemory(view, data);
        return result.data.buffer.byteLength;
      } else {
        let buffer = new Uint8Array(wLength);
        for (let i = 0; i < wLength; ++i)
          buffer[i] = getValue(data + i, 'i8');

        let result = await this.libusb_device.controlTransferOut(setup, buffer);
        if (result.status != 'ok') {
          console.error('controlTransferOut', result);
          return 0;
        }
        return result.bytesWritten;
      }
    });
  }, bmRequestType, bRequest, wValue, wIndex, data, wLength, timeout);
}

static void print(const char* line) { std::cout << line << std::endl; }

static void print(const char* line, int value, bool hex=false) {
  if (hex)
    std::cout << line << std::hex << value << std::dec << std::endl;
  else
    std::cout << line << value << std::endl;
}

static void print_device(const struct libusb_device* dev) {
  print("USB Device");
  print("  Bus: ",  dev->bus_number);
  print("  Port: ", dev->port_number);
  print("  Descriptor");
  print("    bLength: ",            dev->descriptor.bLength);
  print("    bDescriptorType: ",    dev->descriptor.bDescriptorType);
  print("    bcdUSB: 0x",           dev->descriptor.bcdUSB, /*hex=*/true);
  print("    bDeviceClass: ",       dev->descriptor.bDeviceClass);
  print("    bDeviceSubClass: ",    dev->descriptor.bDeviceSubClass);
  print("    bDeviceProtocol: ",    dev->descriptor.bDeviceProtocol);
  print("    bMaxPacketSize0: ",    dev->descriptor.bMaxPacketSize0);
  print("    idVendor: 0x",         dev->descriptor.idVendor, /*hex=*/true);
  print("    idProduct: 0x",        dev->descriptor.idProduct, /*hex=*/true);
  print("    bcdDevice: 0x",        dev->descriptor.bcdDevice, /*hex=*/true);
  print("    iManufacturer: ",      dev->descriptor.iManufacturer);
  print("    iProduct: ",           dev->descriptor.iProduct);
  print("    iSerialNumber: ",      dev->descriptor.iSerialNumber);
  print("    bNumConfigurations: ", dev->descriptor.bNumConfigurations);
}

extern "C" {

int libusb_init(libusb_context **ctx) {
  LIBUSB_LOG("libusb_init");

  if (!EM_ASM_INT(return navigator.usb !== undefined))
    return LIBUSB_ERROR_NOT_SUPPORTED;

  *ctx = new libusb_context;
  return LIBUSB_SUCCESS;
}

void LIBUSB_CALL libusb_exit(libusb_context *ctx) {
  LIBUSB_LOG("libusb_exit");
  delete ctx;
}

void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level) {
  LIBUSB_LOG("libusb_set_debug [NOT IMPLEMENTED]");
}

const struct libusb_version* LIBUSB_CALL libusb_get_version() {
  LIBUSB_LOG("libusb_get_version");
  return &kVersion;
}

struct libusb_transfer* LIBUSB_CALL libusb_alloc_transfer(int iso_packets) {
  LIBUSB_LOG("libusb_alloc_transfer");

  size_t size = sizeof(struct libusb_transfer) +
                sizeof(struct libusb_iso_packet_descriptor) * iso_packets;

  return reinterpret_cast<libusb_transfer*>(calloc(1, size));
}

int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer) {
  LIBUSB_LOG("libusb_submit_transfer");

  bool dir_in = (transfer->endpoint & 0x80) == 0x80;
  uint8_t endpoint = transfer->endpoint & 0x7f;

  switch (transfer->type) {
    case LIBUSB_TRANSFER_TYPE_BULK:
    case LIBUSB_TRANSFER_TYPE_INTERRUPT:
      if (dir_in) {
        MAIN_THREAD_ASYNC_EM_ASM({
          this.libusb_device.transferIn($0, $2).then(function(result) {
            var data = new Uint8Array(result.data.buffer);
            writeArrayToMemory(data, $1);
            _set_transfer_completed($3, data.length);
          }).catch(function(error) {
            console.error('transferIn', error);
            _set_transfer_error($3);
          });
        }, endpoint, transfer->buffer, transfer->length, transfer);
      } else {
        MAIN_THREAD_ASYNC_EM_ASM({
          var data = new Uint8Array($2);
          for(let i = 0; i < $2; ++i)
            data[i] = getValue($1 + i, 'i8');

          this.libusb_device.transferOut($0, data).then(function(result) {
            _set_transfer_completed($3, result.bytesWritten);
          }).catch(function(error) {
            console.error('transferOut', error);
            _set_transfer_error($3);
          });
        }, endpoint, transfer->buffer, transfer->length, transfer);
      }
      break;
    default:
      LIBUSB_LOG("Transfer type not implemented: %u\n", transfer->type);
      return LIBUSB_ERROR_IO;
  }
  return LIBUSB_SUCCESS;
}

int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer) {
  LIBUSB_LOG("libusb_cancel_transfer [NOT IMPLEMENTED]");
  return 0;
}

void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer) {
  LIBUSB_LOG("libusb_free_transfer");
  free(transfer);
}

uint8_t libusb_get_port_number(libusb_device * dev) {
  LIBUSB_LOG("libusb_get_port_number");
  return dev->port_number;
}

int libusb_get_port_numbers(libusb_device *dev,uint8_t *port_numbers, int port_numbers_len) {
  LIBUSB_LOG("libusb_get_port_numbers");

  if (port_numbers_len <= 0)
    return LIBUSB_ERROR_INVALID_PARAM;

  if (port_numbers_len < 1)
    return LIBUSB_ERROR_OVERFLOW;

  port_numbers[0] = dev->port_number;
  return 1;
}

int LIBUSB_CALL libusb_handle_events(libusb_context *ctx) {
  LIBUSB_LOG("libusb_handle_events");

  while (true) {
    if (auto item = ctx->completed_transfers.Pop(25/*ms*/)) {
      auto* transfer = item.value();
      transfer->callback(transfer);
    } else {
      break;
    }
  }
  return LIBUSB_SUCCESS;
}

int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev) {
  LIBUSB_LOG("libusb_reset_device");

  return MAIN_THREAD_EM_ASM_INT({
    return Asyncify.handleAsync(async () => {
      try {
        await this.libusb_device.reset();
        return 0;  // LIBUSB_SUCCESS
      } catch (error) {
        console.error('reset', error);
        // TODO: return -1;  // LIBUSB_ERROR_IO
        return 0;  // LIBUSB_SUCCESS
      }
    });
  });
}

int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle,
    uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
    unsigned char *data, uint16_t wLength, unsigned int timeout) {
  LIBUSB_LOG("libusb_control_transfer");
  return js_control_transfer(request_type, bRequest, wValue, wIndex, data,
                             wLength, timeout);
}

int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle,
    unsigned char endpoint, unsigned char *data, int length,
    int *actual_length, unsigned int timeout) {
  LIBUSB_LOG("libusb_bulk_transfer [NOT IMPLEMENTED]");
  return 0;
}

int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle,
    unsigned char endpoint, unsigned char *data, int length,
    int *actual_length, unsigned int timeout) {
  LIBUSB_LOG("libusb_interrupt_transfer [NOT IMPLEMENTED]");
  return 0;
}

int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle) {
  LIBUSB_LOG("libusb_open");
  // TODO: check dev->descriptor.idVendor and dev->descriptor.idProduct
  MAIN_THREAD_EM_ASM_INT({
    return Asyncify.handleAsync(async () => {
      await this.libusb_device.open();
      try {
        // TODO: Avoid resetting on open.
        await this.libusb_device.reset();
      } catch (error) {
        console.error('reset', error);
      }
      return 1;
    });
  });

  if (handle) {
    *handle = new libusb_device_handle;
    (*handle)->dev = dev;
  }

  return LIBUSB_SUCCESS;
}

void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle) {
  LIBUSB_LOG("libusb_close");

  MAIN_THREAD_EM_ASM_INT({
    Asyncify.handleAsync(async () => {
      return await this.libusb_device.close();
    });
  });

  delete dev_handle;
}

libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle) {
  LIBUSB_LOG("libusb_get_device");
  return dev_handle->dev;
}

ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, libusb_device ***list) {
  LIBUSB_LOG("libusb_get_device_list");

  auto* dev = &ctx->dev;
  dev->ctx = ctx;

  if (js_request_device(dev)) {
    print_device(dev);
    *list = new libusb_device*[]{dev, nullptr};
    return 1;
  } else {
    *list = new libusb_device*[]{nullptr};
    return 0;
  }
}

void LIBUSB_CALL libusb_free_device_list(libusb_device* *list, int unref_devices) {
  LIBUSB_LOG("libusb_free_device_list: unref_devices=%d", unref_devices);

  int i = 0;
  while (true) {
    libusb_device *device = list[i++];
    if (device == nullptr) break;
    delete device;
  }

  delete [] list;
}

int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, struct libusb_device_descriptor *desc) {
  LIBUSB_LOG("libusb_get_device_descriptor");
  *desc = dev->descriptor;
  return 0;
}

int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev) {
  LIBUSB_LOG("libusb_get_device_speed");
  return LIBUSB_SPEED_SUPER;  // TODO: Implement.
}

uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev) {
  LIBUSB_LOG("libusb_get_bus_number");
  return dev->bus_number;
}

int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev,
                                         int configuration) {
  LIBUSB_LOG("libusb_set_configuration [NOT IMPLEMENTED]");
  return 0;
}

int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev,
                                       int interface_number) {
  LIBUSB_LOG("libusb_claim_interface: interface_number=%d", interface_number);
  return MAIN_THREAD_EM_ASM_INT({
    return Asyncify.handleAsync(async () => {
      try {
        await this.libusb_device.claimInterface($0);
        return 0;  // LIBUSB_SUCCESS
      } catch (error) {
        console.error('claimInterface:', error);
        return -1;  // LIBUSB_ERROR_IO
      }
    });
  }, interface_number);
}

int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev,
                                         int interface_number) {
  LIBUSB_LOG("libusb_release_interface: interface_number=%d", interface_number);
  return MAIN_THREAD_EM_ASM_INT({
    return Asyncify.handleAsync(async () => {
      try {
        await this.libusb_device.releaseInterface($0);
        return 0;  // LIBUSB_SUCCESS
      } catch (error) {
        console.error('releaseInterface:', error);
        return -1;  // LIBUSB_ERROR_IO
      }
    });
  }, interface_number);
}


EMSCRIPTEN_KEEPALIVE
void set_transfer_error(struct libusb_transfer* transfer) {
  LIBUSB_LOG("set_tansfer_error: transfer=%p", transfer);
  libusb_context* ctx = transfer->dev_handle->dev->ctx;

  transfer->status = LIBUSB_TRANSFER_CANCELLED;
  transfer->actual_length = 0;

  ctx->completed_transfers.Push(transfer);
}

EMSCRIPTEN_KEEPALIVE
void set_transfer_completed(struct libusb_transfer* transfer, int actual_length) {
  LIBUSB_LOG("set_tansfer_completed: transfer=%p, actual_length=%d",
             transfer, actual_length);
  libusb_context* ctx = transfer->dev_handle->dev->ctx;

  transfer->status = LIBUSB_TRANSFER_COMPLETED;
  transfer->actual_length = actual_length;

  ctx->completed_transfers.Push(transfer);
}

EMSCRIPTEN_KEEPALIVE
void fill_device(struct libusb_device* dev,
    uint16_t bcdUSB,
    uint8_t bDeviceClass,
    uint8_t bDeviceSubClass,
    uint8_t bDeviceProtocol,
    uint16_t idVendor,
    uint16_t idProduct,
    uint16_t  bcdDevice,
    uint8_t bNumConfigurations) {
  dev->bus_number = 0;
  dev->port_number = 1;

  struct libusb_device_descriptor* d = &dev->descriptor;
  d->bLength = LIBUSB_DT_DEVICE_SIZE;
  d->bDescriptorType = LIBUSB_DT_DEVICE;
  d->bcdUSB = bcdUSB;
  d->bDeviceClass = bDeviceClass;
  d->bDeviceSubClass = bDeviceSubClass;
  d->bDeviceProtocol = bDeviceProtocol;
  d->bMaxPacketSize0 = 64;
  d->idVendor = idVendor;
  d->idProduct = idProduct;
  d->bcdDevice = bcdDevice;
  d->iManufacturer = 1;
  d->iProduct = 2;
  d->iSerialNumber = 3;
  d->bNumConfigurations = bNumConfigurations;
}

}  // extern "C"
