// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device/usb/usb_device_win.h"

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/device_event_log/device_event_log.h"
#include "device/usb/usb_device_handle_win.h"
#include "device/usb/webusb_descriptors.h"

#include <windows.h>

namespace device {

namespace {
const uint16_t kUsbVersion2_1 = 0x0210;
}  // namespace

UsbDeviceWin::UsbDeviceWin(const std::string& device_path,
                           const std::string& hub_path,
                           uint32_t bus_number,
                           uint32_t port_number,
                           const std::string& driver_name)
    : UsbDevice(bus_number, port_number),
      device_path_(device_path),
      hub_path_(hub_path),
      driver_name_(driver_name) {}

UsbDeviceWin::~UsbDeviceWin() {}

void UsbDeviceWin::Open(OpenCallback callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  scoped_refptr<UsbDeviceHandle> device_handle;
  if (base::EqualsCaseInsensitiveASCII(driver_name_, "winusb"))
    device_handle = new UsbDeviceHandleWin(this, false);
  // TODO: Support composite devices.
  // else if (base::EqualsCaseInsensitiveASCII(driver_name_, "usbccgp"))
  //  device_handle = new UsbDeviceHandleWin(this, true);

  base::SequencedTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback), device_handle));
}

void UsbDeviceWin::ReadDescriptors(base::OnceCallback<void(bool)> callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  scoped_refptr<UsbDeviceHandle> device_handle;
  base::win::ScopedHandle handle(
      CreateFileA(hub_path_.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr,
                  OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr));
  if (handle.IsValid()) {
    device_handle = new UsbDeviceHandleWin(this, std::move(handle));
  } else {
    USB_PLOG(ERROR) << "Failed to open " << hub_path_;
    std::move(callback).Run(false);
    return;
  }

  ReadUsbDescriptors(device_handle,
                     base::BindOnce(&UsbDeviceWin::OnReadDescriptors, this,
                                    std::move(callback), device_handle));
}

void UsbDeviceWin::OnReadDescriptors(
    base::OnceCallback<void(bool)> callback,
    scoped_refptr<UsbDeviceHandle> device_handle,
    std::unique_ptr<UsbDeviceDescriptor> descriptor) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!descriptor) {
    USB_LOG(ERROR) << "Failed to read descriptors from " << device_path_ << ".";
    device_handle->Close();
    std::move(callback).Run(false);
    return;
  }

  descriptor_ = *descriptor;

  // WinUSB only supports the configuration 1.
  ActiveConfigurationChanged(1);

  auto string_map = std::make_unique<std::map<uint8_t, base::string16>>();
  if (descriptor_.i_manufacturer)
    (*string_map)[descriptor_.i_manufacturer] = base::string16();
  if (descriptor_.i_product)
    (*string_map)[descriptor_.i_product] = base::string16();
  if (descriptor_.i_serial_number)
    (*string_map)[descriptor_.i_serial_number] = base::string16();

  ReadUsbStringDescriptors(
      device_handle, std::move(string_map),
      base::BindOnce(&UsbDeviceWin::OnReadStringDescriptors, this,
                     std::move(callback), device_handle));
}

void UsbDeviceWin::OnReadStringDescriptors(
    base::OnceCallback<void(bool)> callback,
    scoped_refptr<UsbDeviceHandle> device_handle,
    std::unique_ptr<std::map<uint8_t, base::string16>> string_map) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  device_handle->Close();

  if (descriptor_.i_manufacturer)
    manufacturer_string_ = (*string_map)[descriptor_.i_manufacturer];
  if (descriptor_.i_product)
    product_string_ = (*string_map)[descriptor_.i_product];
  if (descriptor_.i_serial_number)
    serial_number_ = (*string_map)[descriptor_.i_serial_number];

  if (usb_version() >= kUsbVersion2_1) {
    Open(base::BindOnce(&UsbDeviceWin::OnOpenedToReadWebUsbDescriptors, this,
                        std::move(callback)));
  } else {
    std::move(callback).Run(true);
  }
}

void UsbDeviceWin::OnOpenedToReadWebUsbDescriptors(
    base::OnceCallback<void(bool)> callback,
    scoped_refptr<UsbDeviceHandle> device_handle) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (!device_handle) {
    USB_LOG(ERROR) << "Failed to open device to read WebUSB descriptors.";
    // Failure to read WebUSB descriptors is not fatal.
    std::move(callback).Run(true);
    return;
  }

  ReadWebUsbDescriptors(
      device_handle,
      base::BindRepeating(&UsbDeviceWin::OnReadWebUsbDescriptors, this,
                          base::Passed(&callback), device_handle));
}

void UsbDeviceWin::OnReadWebUsbDescriptors(
    base::OnceCallback<void(bool)> callback,
    scoped_refptr<UsbDeviceHandle> device_handle,
    const GURL& landing_page) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  webusb_landing_page_ = landing_page;

  device_handle->Close();
  std::move(callback).Run(true);
}

}  // namespace device
