// Copyright 2018 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 "raw_input_gamepad_device_win.h"

#include "base/stl_util.h"
#include "device/gamepad/gamepad_data_fetcher.h"

namespace device {

namespace {

float NormalizeAxis(long value, long min, long max) {
  return (2.f * (value - min) / static_cast<float>(max - min)) - 1.f;
}

unsigned long GetBitmask(unsigned short bits) {
  return (1 << bits) - 1;
}

const uint32_t kGenericDesktopUsagePage = 0x01;
const uint32_t kGameControlsUsagePage = 0x05;
const uint32_t kButtonUsagePage = 0x09;
const uint32_t kConsumerUsagePage = 0x0c;

const uint32_t kAxisMinimumUsageNumber = 0x30;
const uint32_t kSystemMainMenuUsageNumber = 0x85;
const uint32_t kPowerUsageNumber = 0x30;
const uint32_t kSearchUsageNumber = 0x0221;
const uint32_t kHomeUsageNumber = 0x0223;
const uint32_t kBackUsageNumber = 0x0224;

// Vendor IDs.
const uint32_t kVendorOculus = 0x2833;
const uint32_t kVendorBlue = 0xb58e;
const uint32_t kVendorMicrosoft = 0x045e;

// Product IDs.
const uint32_t kProductSurfacePro2017Keyboard = 0x0922;

struct VendorProductPair {
  const uint16_t vendor;
  const uint16_t product;
} kFilteredDevices[] = {
    // The Surface Pro 2017's detachable keyboard is a composite device with
    // several HID sub-devices. Filter out the keyboard's device ID to avoid
    // treating these sub-devices as gamepads.
    {kVendorMicrosoft, kProductSurfacePro2017Keyboard},
};
const size_t kFilteredDevicesLen = base::size(kFilteredDevices);

// The fetcher will collect all HID usages from the Button usage page and any
// additional usages listed below.
struct SpecialUsages {
  const uint16_t usage_page;
  const uint16_t usage;
} kSpecialUsages[] = {
    // Xbox One S pre-FW update reports Xbox button as SystemMainMenu over BT.
    {kGenericDesktopUsagePage, kSystemMainMenuUsageNumber},
    // Power is used for the Guide button on the Nvidia Shield 2015 gamepad.
    {kConsumerUsagePage, kPowerUsageNumber},
    // Search is used for the Guide button on the Nvidia Shield 2017 gamepad.
    {kConsumerUsagePage, kSearchUsageNumber},
    // Start, Back, and Guide buttons are often reported as Consumer Home or
    // Back.
    {kConsumerUsagePage, kHomeUsageNumber},
    {kConsumerUsagePage, kBackUsageNumber},
};
const size_t kSpecialUsagesLen = base::size(kSpecialUsages);

}  // namespace

RawInputGamepadDeviceWin::RawInputGamepadDeviceWin(
    HANDLE device_handle,
    int source_id,
    HidDllFunctionsWin* hid_functions)
    : handle_(device_handle),
      source_id_(source_id),
      last_update_timestamp_(GamepadDataFetcher::CurrentTimeInMicroseconds()),
      hid_functions_(hid_functions) {
  ::ZeroMemory(buttons_, sizeof(buttons_));
  ::ZeroMemory(axes_, sizeof(axes_));

  if (hid_functions_->IsValid())
    is_valid_ = QueryDeviceInfo();

  if (is_valid_) {
    if (Dualshock4ControllerWin::IsDualshock4(vendor_id_, product_id_)) {
      dualshock4_ = std::make_unique<Dualshock4ControllerWin>(handle_);
    } else if (HidHapticGamepadWin::IsHidHaptic(vendor_id_, product_id_)) {
      hid_haptics_ =
          HidHapticGamepadWin::Create(vendor_id_, product_id_, handle_);
    }
  }
}

RawInputGamepadDeviceWin::~RawInputGamepadDeviceWin() = default;

// static
bool RawInputGamepadDeviceWin::IsGamepadUsageId(uint16_t usage) {
  return usage == kGenericDesktopJoystick || usage == kGenericDesktopGamePad ||
         usage == kGenericDesktopMultiAxisController;
}

void RawInputGamepadDeviceWin::DoShutdown() {
  if (dualshock4_)
    dualshock4_->Shutdown();
  dualshock4_.reset();
  if (hid_haptics_)
    hid_haptics_->Shutdown();
  hid_haptics_.reset();
}

void RawInputGamepadDeviceWin::UpdateGamepad(RAWINPUT* input) {
  DCHECK(hid_functions_->IsValid());
  NTSTATUS status;

  // Query button state.
  if (buttons_length_ > 0) {
    // Clear the button state
    ::ZeroMemory(buttons_, sizeof(buttons_));
    ULONG buttons_length = 0;

    hid_functions_->HidPGetUsagesEx()(
        HidP_Input, 0, nullptr, &buttons_length, preparsed_data_,
        reinterpret_cast<PCHAR>(input->data.hid.bRawData),
        input->data.hid.dwSizeHid);

    std::unique_ptr<USAGE_AND_PAGE[]> usages(
        new USAGE_AND_PAGE[buttons_length]);
    status = hid_functions_->HidPGetUsagesEx()(
        HidP_Input, 0, usages.get(), &buttons_length, preparsed_data_,
        reinterpret_cast<PCHAR>(input->data.hid.bRawData),
        input->data.hid.dwSizeHid);

    if (status == HIDP_STATUS_SUCCESS) {
      // Set each reported button to true.
      for (size_t j = 0; j < buttons_length; j++) {
        uint16_t usage_page = usages[j].UsagePage;
        uint16_t usage = usages[j].Usage;
        if (usage_page == kButtonUsagePage && usage > 0) {
          size_t button_index = size_t{usage - 1};
          if (button_index < Gamepad::kButtonsLengthCap)
            buttons_[button_index] = true;
        } else if (usage_page != kButtonUsagePage &&
                   !special_button_map_.empty()) {
          for (size_t special_index = 0; special_index < kSpecialUsagesLen;
               ++special_index) {
            int button_index = special_button_map_[special_index];
            if (button_index < 0)
              continue;
            const auto& special = kSpecialUsages[special_index];
            if (usage_page == special.usage_page && usage == special.usage)
              buttons_[button_index] = true;
          }
        }
      }
    }
  }

  // Query axis state.
  ULONG axis_value = 0;
  LONG scaled_axis_value = 0;
  for (uint32_t i = 0; i < axes_length_; i++) {
    RawGamepadAxis* axis = &axes_[i];

    // If the min is < 0 we have to query the scaled value, otherwise we need
    // the normal unscaled value.
    if (axis->caps.LogicalMin < 0) {
      status = hid_functions_->HidPGetScaledUsageValue()(
          HidP_Input, axis->caps.UsagePage, 0, axis->caps.Range.UsageMin,
          &scaled_axis_value, preparsed_data_,
          reinterpret_cast<PCHAR>(input->data.hid.bRawData),
          input->data.hid.dwSizeHid);
      if (status == HIDP_STATUS_SUCCESS) {
        axis->value = NormalizeAxis(scaled_axis_value, axis->caps.PhysicalMin,
                                    axis->caps.PhysicalMax);
      }
    } else {
      status = hid_functions_->HidPGetUsageValue()(
          HidP_Input, axis->caps.UsagePage, 0, axis->caps.Range.UsageMin,
          &axis_value, preparsed_data_,
          reinterpret_cast<PCHAR>(input->data.hid.bRawData),
          input->data.hid.dwSizeHid);
      if (status == HIDP_STATUS_SUCCESS) {
        axis->value = NormalizeAxis(axis_value & axis->bitmask,
                                    axis->caps.LogicalMin & axis->bitmask,
                                    axis->caps.LogicalMax & axis->bitmask);
      }
    }
  }

  last_update_timestamp_ = GamepadDataFetcher::CurrentTimeInMicroseconds();
}

void RawInputGamepadDeviceWin::ReadPadState(Gamepad* pad) const {
  DCHECK(pad);

  pad->timestamp = last_update_timestamp_;
  pad->buttons_length = buttons_length_;
  pad->axes_length = axes_length_;

  for (unsigned int i = 0; i < buttons_length_; i++) {
    pad->buttons[i].pressed = buttons_[i];
    pad->buttons[i].value = buttons_[i] ? 1.0 : 0.0;
  }

  for (unsigned int i = 0; i < axes_length_; i++)
    pad->axes[i] = axes_[i].value;
}

bool RawInputGamepadDeviceWin::SupportsVibration() const {
  return dualshock4_ || hid_haptics_;
}

void RawInputGamepadDeviceWin::SetVibration(double strong_magnitude,
                                            double weak_magnitude) {
  if (dualshock4_)
    dualshock4_->SetVibration(strong_magnitude, weak_magnitude);
  else if (hid_haptics_)
    hid_haptics_->SetVibration(strong_magnitude, weak_magnitude);
}

bool RawInputGamepadDeviceWin::QueryDeviceInfo() {
  // Fetch HID properties (RID_DEVICE_INFO_HID) for this device. This includes
  // |vendor_id_|, |product_id_|, |version_number_|, and |usage_|.
  if (!QueryHidInfo())
    return false;

  // Make sure this device is of a type that we want to observe.
  if (!IsGamepadUsageId(usage_))
    return false;

  // This is terrible, but the Oculus Rift and some Blue Yeti microphones seem
  // to think they are gamepads. Filter out any such devices. Oculus Touch is
  // handled elsewhere.
  if (vendor_id_ == kVendorOculus || vendor_id_ == kVendorBlue)
    return false;

  for (size_t i = 0; i < kFilteredDevicesLen; ++i) {
    const auto& filter = kFilteredDevices[i];
    if (vendor_id_ == filter.vendor && product_id_ == filter.product)
      return false;
  }

  // Fetch the device's |name_| (RIDI_DEVICENAME).
  if (!QueryDeviceName())
    return false;

  // From the name we can guess at the bus type. PCI HID devices have "VEN" and
  // "DEV" instead of "VID" and "PID". PCI HID devices are typically not
  // gamepads and are ignored.
  // Example PCI device name: \\?\HID#VEN_1234&DEV_ABCD
  // TODO(crbug/881539): Potentially allow PCI HID devices to be enumerated, but
  // prefer known gamepads when there is contention.
  std::wstring pci_prefix = L"\\\\?\\HID#VEN_";
  if (!name_.compare(0, pci_prefix.size(), pci_prefix))
    return false;

  // Fetch the human-friendly |product_string_|, if available.
  if (!QueryProductString())
    product_string_ = L"Unknown Gamepad";

  // Fetch information about the buttons and axes on this device. This sets
  // |buttons_length_| and |axes_length_| to their correct values and populates
  // |axes_| with capabilities info.
  if (!QueryDeviceCapabilities())
    return false;

  // Gamepads must have at least one button or axis.
  if (buttons_length_ == 0 && axes_length_ == 0)
    return false;

  return true;
}

bool RawInputGamepadDeviceWin::QueryHidInfo() {
  UINT size = 0;

  UINT result =
      ::GetRawInputDeviceInfo(handle_, RIDI_DEVICEINFO, nullptr, &size);
  if (result == static_cast<UINT>(-1)) {
    PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
    return false;
  }
  DCHECK_EQ(0u, result);

  std::unique_ptr<uint8_t[]> buffer(new uint8_t[size]);
  result =
      ::GetRawInputDeviceInfo(handle_, RIDI_DEVICEINFO, buffer.get(), &size);
  if (result == static_cast<UINT>(-1)) {
    PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
    return false;
  }
  DCHECK_EQ(size, result);
  RID_DEVICE_INFO* device_info =
      reinterpret_cast<RID_DEVICE_INFO*>(buffer.get());

  DCHECK_EQ(device_info->dwType, static_cast<DWORD>(RIM_TYPEHID));
  vendor_id_ = static_cast<uint16_t>(device_info->hid.dwVendorId);
  product_id_ = static_cast<uint16_t>(device_info->hid.dwProductId);
  version_number_ = static_cast<uint16_t>(device_info->hid.dwVersionNumber);
  usage_ = device_info->hid.usUsage;

  return true;
}

bool RawInputGamepadDeviceWin::QueryDeviceName() {
  UINT size = 0;

  UINT result =
      ::GetRawInputDeviceInfo(handle_, RIDI_DEVICENAME, nullptr, &size);
  if (result == static_cast<UINT>(-1)) {
    PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
    return false;
  }
  DCHECK_EQ(0u, result);

  std::unique_ptr<wchar_t[]> buffer(new wchar_t[size]);
  result =
      ::GetRawInputDeviceInfo(handle_, RIDI_DEVICENAME, buffer.get(), &size);
  if (result == static_cast<UINT>(-1)) {
    PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
    return false;
  }
  DCHECK_EQ(size, result);

  name_ = buffer.get();

  return true;
}

bool RawInputGamepadDeviceWin::QueryProductString() {
  DCHECK(hid_functions_);
  DCHECK(hid_functions_->IsValid());
  base::win::ScopedHandle hid_handle(::CreateFile(
      name_.c_str(), GENERIC_READ | GENERIC_WRITE,
      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL));
  if (!hid_handle.IsValid())
    return false;
  product_string_.resize(Gamepad::kIdLengthCap);
  return hid_functions_->HidDGetProductString()(
      hid_handle.Get(), &product_string_.front(), Gamepad::kIdLengthCap);
}

bool RawInputGamepadDeviceWin::QueryDeviceCapabilities() {
  DCHECK(hid_functions_);
  DCHECK(hid_functions_->IsValid());
  UINT size = 0;

  UINT result =
      ::GetRawInputDeviceInfo(handle_, RIDI_PREPARSEDDATA, nullptr, &size);
  if (result == static_cast<UINT>(-1)) {
    PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
    return false;
  }
  DCHECK_EQ(0u, result);

  ppd_buffer_.reset(new uint8_t[size]);
  preparsed_data_ = reinterpret_cast<PHIDP_PREPARSED_DATA>(ppd_buffer_.get());
  result = ::GetRawInputDeviceInfo(handle_, RIDI_PREPARSEDDATA,
                                   ppd_buffer_.get(), &size);
  if (result == static_cast<UINT>(-1)) {
    PLOG(ERROR) << "GetRawInputDeviceInfo() failed";
    return false;
  }
  DCHECK_EQ(size, result);

  HIDP_CAPS caps;
  NTSTATUS status = hid_functions_->HidPGetCaps()(preparsed_data_, &caps);
  DCHECK_EQ(HIDP_STATUS_SUCCESS, status);

  QueryButtonCapabilities(caps.NumberInputButtonCaps);
  QueryAxisCapabilities(caps.NumberInputValueCaps);

  return true;
}

void RawInputGamepadDeviceWin::QueryButtonCapabilities(uint16_t button_count) {
  DCHECK(hid_functions_);
  DCHECK(hid_functions_->IsValid());
  if (button_count > 0) {
    std::unique_ptr<HIDP_BUTTON_CAPS[]> button_caps(
        new HIDP_BUTTON_CAPS[button_count]);
    NTSTATUS status = hid_functions_->HidPGetButtonCaps()(
        HidP_Input, button_caps.get(), &button_count, preparsed_data_);
    DCHECK_EQ(HIDP_STATUS_SUCCESS, status);

    // Keep track of which button indices are in use.
    std::vector<bool> button_indices_used(Gamepad::kButtonsLengthCap, false);

    // Collect all inputs from the Button usage page.
    QueryNormalButtonCapabilities(button_caps.get(), button_count,
                                  &button_indices_used);

    // Check for common gamepad buttons that are not on the Button usage page.
    QuerySpecialButtonCapabilities(button_caps.get(), button_count,
                                   &button_indices_used);
  }
}

void RawInputGamepadDeviceWin::QueryNormalButtonCapabilities(
    HIDP_BUTTON_CAPS button_caps[],
    uint16_t button_count,
    std::vector<bool>* button_indices_used) {
  DCHECK(button_caps);
  DCHECK(button_indices_used);

  // Collect all inputs from the Button usage page and assign button indices
  // based on the usage value.
  for (size_t i = 0; i < button_count; ++i) {
    uint16_t usage_page = button_caps[i].UsagePage;
    uint16_t usage_min = button_caps[i].Range.UsageMin;
    uint16_t usage_max = button_caps[i].Range.UsageMax;
    if (usage_min == 0 || usage_max == 0)
      continue;
    size_t button_index_min = size_t{usage_min - 1};
    size_t button_index_max = size_t{usage_max - 1};
    if (usage_page == kButtonUsagePage &&
        button_index_min < Gamepad::kButtonsLengthCap) {
      button_index_max =
          std::min(Gamepad::kButtonsLengthCap - 1, button_index_max);
      buttons_length_ = std::max(buttons_length_, button_index_max + 1);
      for (size_t j = button_index_min; j <= button_index_max; ++j)
        (*button_indices_used)[j] = true;
    }
  }
}

void RawInputGamepadDeviceWin::QuerySpecialButtonCapabilities(
    HIDP_BUTTON_CAPS button_caps[],
    uint16_t button_count,
    std::vector<bool>* button_indices_used) {
  DCHECK(button_caps);
  DCHECK(button_indices_used);

  // Check for common gamepad buttons that are not on the Button usage page.
  std::vector<bool> has_special_usage(kSpecialUsagesLen, false);
  size_t unmapped_button_count = 0;
  for (size_t i = 0; i < button_count; ++i) {
    uint16_t usage_page = button_caps[i].UsagePage;
    uint16_t usage_min = button_caps[i].Range.UsageMin;
    uint16_t usage_max = button_caps[i].Range.UsageMax;
    for (size_t special_index = 0; special_index < kSpecialUsagesLen;
         ++special_index) {
      const auto& special = kSpecialUsages[special_index];
      if (usage_page == special.usage_page && usage_min <= special.usage &&
          usage_max >= special.usage) {
        has_special_usage[special_index] = true;
        ++unmapped_button_count;
      }
    }
  }

  special_button_map_.clear();
  if (unmapped_button_count > 0) {
    // Insert special buttons at unused button indices.
    special_button_map_.resize(kSpecialUsagesLen, -1);
    size_t button_index = 0;
    for (size_t special_index = 0; special_index < kSpecialUsagesLen;
         ++special_index) {
      if (!has_special_usage[special_index])
        continue;

      // Advance to the next unused button index.
      while (button_index < Gamepad::kButtonsLengthCap &&
             (*button_indices_used)[button_index]) {
        ++button_index;
      }
      if (button_index >= Gamepad::kButtonsLengthCap)
        break;

      special_button_map_[special_index] = button_index;
      (*button_indices_used)[button_index] = true;
      ++button_index;

      if (--unmapped_button_count == 0)
        break;
    }
  }
}

void RawInputGamepadDeviceWin::QueryAxisCapabilities(uint16_t axis_count) {
  DCHECK(hid_functions_);
  DCHECK(hid_functions_->IsValid());
  std::unique_ptr<HIDP_VALUE_CAPS[]> axes_caps(new HIDP_VALUE_CAPS[axis_count]);
  hid_functions_->HidPGetValueCaps()(HidP_Input, axes_caps.get(), &axis_count,
                                     preparsed_data_);

  bool mapped_all_axes = true;

  for (size_t i = 0; i < axis_count; i++) {
    size_t axis_index = axes_caps[i].Range.UsageMin - kAxisMinimumUsageNumber;
    if (axis_index < Gamepad::kAxesLengthCap && !axes_[axis_index].active) {
      axes_[axis_index].caps = axes_caps[i];
      axes_[axis_index].value = 0;
      axes_[axis_index].active = true;
      axes_[axis_index].bitmask = GetBitmask(axes_caps[i].BitSize);
      axes_length_ = std::max(axes_length_, axis_index + 1);
    } else {
      mapped_all_axes = false;
    }
  }

  if (!mapped_all_axes) {
    // For axes whose usage puts them outside the standard axesLengthCap range.
    size_t next_index = 0;
    for (size_t i = 0; i < axis_count; i++) {
      size_t usage = axes_caps[i].Range.UsageMin - kAxisMinimumUsageNumber;
      if (usage >= Gamepad::kAxesLengthCap &&
          axes_caps[i].UsagePage <= kGameControlsUsagePage) {
        for (; next_index < Gamepad::kAxesLengthCap; ++next_index) {
          if (!axes_[next_index].active)
            break;
        }
        if (next_index < Gamepad::kAxesLengthCap) {
          axes_[next_index].caps = axes_caps[i];
          axes_[next_index].value = 0;
          axes_[next_index].active = true;
          axes_[next_index].bitmask = GetBitmask(axes_caps[i].BitSize);
          axes_length_ = std::max(axes_length_, next_index + 1);
        }
      }

      if (next_index >= Gamepad::kAxesLengthCap)
        break;
    }
  }
}

}  // namespace device
