// Copyright 2018 The Chromium OS 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 "permission_broker/libusb_wrapper.h"
#include "permission_broker/usb_control.h"

#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include <libusb-1.0/libusb.h>
#include <linux/usb/ch11.h>

#include <base/bind.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <base/threading/platform_thread.h>
#include <base/time/time.h>
#include <brillo/message_loops/message_loop.h>

namespace permission_broker {

// TODO(b/110247560): reimplement with a file-based approach (see
// go/usb-power_ctl).
const UsbDeviceInfo kDeviceAllowList[] = {
    // Huddly camera VID and PID.
    UsbDeviceInfo(0x2bd9, 0x0011, 0xEF /* Miscellaneous */),
    // MIMO VUE HD VID and PID.
    // This is a touch controller with a small screen for CFM devices.
    // https://www.mimomonitors.com/products/mimo-vue-hd-display
    UsbDeviceInfo(0x17e9, 0x416d, 0xFF /* Miscellaneous */),
};

std::string DeviceInfoString(uint16_t vid, uint16_t pid) {
  return base::StringPrintf("(vid: 0x%04x, pid: 0x%04x)", vid, pid);
}

// Utility function used to execute either power-on or power-off on all the
// |devices| passed as parameter. The |is_power_on| flag indicates whether the
// devices will be powered off or on when |is_power_on| is set respectively to
// false or true.
bool SetDevicesPowerState(
    const std::vector<std::unique_ptr<UsbDeviceInterface>>& devices,
    bool is_power_on) {

  bool cumulative_success = true;
  for (auto& device : devices) {
    // Get the parent if it is possible.
    auto parent = device->GetParent();
    if (parent == nullptr) {
      LOG(ERROR) << "Unable to find parent for device (" << device->GetInfo()
                 << ")";
      cumulative_success = false;
      continue;
    }

    std::string state = is_power_on ? "on" : "off";
    LOG(INFO) << "Powering " << state << " USB device (" << device->GetInfo()
              << ")";

    // Set the appropriate power state to the device.
    bool success = parent->SetPowerState(is_power_on, device->GetPort());
    if (!success) {
      LOG(WARNING) << "Unable to power " << state << " device ("
                   << device->GetInfo() << ")";
    }
    // Accumulate the success flag so that we can eventually return the
    // cumulative response value.
    cumulative_success = cumulative_success && success;
  }

  return cumulative_success;
}

// This callback is used to delay the powering on of the provided |devices| by
// |delay|. |cumulative_success| is used to finally return the cumulative
// success value determined by cumulatively collecting all the boolean results
// of all power-off and power-on operations.
void PowerOnDevicesCallback(
    base::Callback<void(bool)> callback,
    const std::vector<std::unique_ptr<UsbDeviceInterface>> devices,
    bool cumulative_success) {

  cumulative_success =
      SetDevicesPowerState(devices, true) && cumulative_success;
  callback.Run(cumulative_success);
}

UsbControl::UsbControl(std::unique_ptr<UsbDeviceManagerInterface> manager)
  : manager_(std::move(manager)) {}

UsbControl::~UsbControl() = default;

bool UsbControl::IsDeviceAllowed(uint16_t vid, uint16_t pid) const {
  return std::find(
      std::begin(kDeviceAllowList),
      std::end(kDeviceAllowList),
      UsbDeviceInfo(vid, pid)) != std::end(kDeviceAllowList);
}

void UsbControl::PowerCycleUsbPorts(
    base::Callback<void(bool)> callback,
    uint16_t vid,
    uint16_t pid,
    base::TimeDelta delay) {

  if (!IsDeviceAllowed(vid, pid)) {
    LOG(ERROR) << "The device is not allowed for USB control "
               << DeviceInfoString(vid, pid);
    callback.Run(false);
    return;
  }

  std::vector<std::unique_ptr<UsbDeviceInterface>> devices =
      manager_->GetDevicesByVidPid(vid, pid);
  if (devices.empty()) {
    LOG(WARNING) << "No device with the provided information was found on the "
                 << "system " << DeviceInfoString(vid, pid);
    callback.Run(false);
    return;
  }

  // Turn off all the devices that were found.
  bool cumulative_success = SetDevicesPowerState(devices, false);

  // After the specified delay, turn all the devices on.
  brillo::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(
          &PowerOnDevicesCallback,
          base::Passed(std::move(callback)),
          base::Passed(std::move(devices)),
          cumulative_success),
      delay);
}

}  // namespace permission_broker
