// 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
