// 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 "device/gamepad/gamepad_device_linux.h"

#include <fcntl.h>
#include <limits.h>
#include <linux/hidraw.h>
#include <linux/input.h>
#include <linux/joystick.h>
#include <sys/ioctl.h>

#include "base/posix/eintr_wrapper.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "device/gamepad/gamepad_data_fetcher.h"
#include "device/udev_linux/udev_linux.h"

namespace device {

namespace {

const char kInputSubsystem[] = "input";
const char kUsbSubsystem[] = "usb";
const char kUsbDeviceType[] = "usb_device";
const float kMaxLinuxAxisValue = 32767.0;
const int kInvalidEffectId = -1;
const uint16_t kRumbleMagnitudeMax = 0xffff;

const size_t kSpecialKeys[] = {
    // Xbox One S pre-FW update reports Xbox button as SystemMainMenu over BT.
    KEY_MENU,
    // Power is used for the Guide button on the Nvidia Shield 2015 gamepad.
    KEY_POWER,
    // Search is used for the Guide button on the Nvidia Shield 2015 gamepad.
    KEY_SEARCH,
    // Start, Back, and Guide buttons are often reported as Consumer Home or
    // Back.
    KEY_HOMEPAGE, KEY_BACK,
};
const size_t kSpecialKeysLen = base::size(kSpecialKeys);

#define LONG_BITS (CHAR_BIT * sizeof(long))
#define BITS_TO_LONGS(x) (((x) + LONG_BITS - 1) / LONG_BITS)

static inline bool test_bit(int bit, const unsigned long* data) {
  return data[bit / LONG_BITS] & (1UL << (bit % LONG_BITS));
}

GamepadBusType GetEvdevBusType(int fd) {
  struct input_id input_info;
  if (HANDLE_EINTR(ioctl(fd, EVIOCGID, &input_info)) >= 0) {
    if (input_info.bustype == BUS_USB)
      return GAMEPAD_BUS_USB;
    if (input_info.bustype == BUS_BLUETOOTH)
      return GAMEPAD_BUS_BLUETOOTH;
  }
  return GAMEPAD_BUS_UNKNOWN;
}

bool HasRumbleCapability(int fd) {
  unsigned long evbit[BITS_TO_LONGS(EV_MAX)];
  unsigned long ffbit[BITS_TO_LONGS(FF_MAX)];

  if (HANDLE_EINTR(ioctl(fd, EVIOCGBIT(0, EV_MAX), evbit)) < 0 ||
      HANDLE_EINTR(ioctl(fd, EVIOCGBIT(EV_FF, FF_MAX), ffbit)) < 0) {
    return false;
  }

  if (!test_bit(EV_FF, evbit)) {
    return false;
  }

  return test_bit(FF_RUMBLE, ffbit);
}

// Check an evdev device for key codes which sometimes appear on gamepads but
// aren't reported by joydev. If a special key is found, the corresponding entry
// of the |has_special_key| vector is set to true. Returns the number of
// special keys found.
size_t CheckSpecialKeys(int fd, std::vector<bool>* has_special_key) {
  DCHECK(has_special_key);
  unsigned long evbit[BITS_TO_LONGS(EV_MAX)];
  unsigned long keybit[BITS_TO_LONGS(KEY_MAX)];
  size_t found_special_keys = 0;

  has_special_key->clear();
  if (HANDLE_EINTR(ioctl(fd, EVIOCGBIT(0, EV_MAX), evbit)) < 0 ||
      HANDLE_EINTR(ioctl(fd, EVIOCGBIT(EV_KEY, KEY_MAX), keybit)) < 0) {
    return 0;
  }

  if (!test_bit(EV_KEY, evbit)) {
    return 0;
  }

  has_special_key->resize(kSpecialKeysLen, false);
  for (size_t special_index = 0; special_index < kSpecialKeysLen;
       ++special_index) {
    (*has_special_key)[special_index] =
        test_bit(kSpecialKeys[special_index], keybit);
    ++found_special_keys;
  }

  return found_special_keys;
}

bool GetHidrawDevinfo(int fd,
                      GamepadBusType* bus_type,
                      uint16_t* vendor_id,
                      uint16_t* product_id) {
  struct hidraw_devinfo info;
  if (HANDLE_EINTR(ioctl(fd, HIDIOCGRAWINFO, &info)) < 0)
    return false;
  if (bus_type) {
    if (info.bustype == BUS_USB)
      *bus_type = GAMEPAD_BUS_USB;
    else if (info.bustype == BUS_BLUETOOTH)
      *bus_type = GAMEPAD_BUS_BLUETOOTH;
    else
      *bus_type = GAMEPAD_BUS_UNKNOWN;
  }
  if (vendor_id)
    *vendor_id = static_cast<uint16_t>(info.vendor);
  if (product_id)
    *product_id = static_cast<uint16_t>(info.product);
  return true;
}

int StoreRumbleEffect(int fd,
                      int effect_id,
                      uint16_t duration,
                      uint16_t start_delay,
                      uint16_t strong_magnitude,
                      uint16_t weak_magnitude) {
  struct ff_effect effect;
  memset(&effect, 0, sizeof(effect));
  effect.type = FF_RUMBLE;
  effect.id = effect_id;
  effect.replay.length = duration;
  effect.replay.delay = start_delay;
  effect.u.rumble.strong_magnitude = strong_magnitude;
  effect.u.rumble.weak_magnitude = weak_magnitude;

  if (HANDLE_EINTR(ioctl(fd, EVIOCSFF, (const void*)&effect)) < 0)
    return kInvalidEffectId;
  return effect.id;
}

void DestroyEffect(int fd, int effect_id) {
  HANDLE_EINTR(ioctl(fd, EVIOCRMFF, effect_id));
}

bool StartOrStopEffect(int fd, int effect_id, bool do_start) {
  struct input_event start_stop;
  memset(&start_stop, 0, sizeof(start_stop));
  start_stop.type = EV_FF;
  start_stop.code = effect_id;
  start_stop.value = do_start ? 1 : 0;
  ssize_t nbytes =
      HANDLE_EINTR(write(fd, (const void*)&start_stop, sizeof(start_stop)));
  return nbytes == sizeof(start_stop);
}

uint16_t HexStringToUInt16WithDefault(base::StringPiece input,
                                      uint16_t default_value) {
  uint32_t out = 0;
  if (!base::HexStringToUInt(input, &out) ||
      out > std::numeric_limits<uint16_t>::max()) {
    return default_value;
  }
  return static_cast<uint16_t>(out);
}

}  // namespace

GamepadDeviceLinux::GamepadDeviceLinux(const std::string& syspath_prefix)
    : syspath_prefix_(syspath_prefix),
      button_indices_used_(Gamepad::kButtonsLengthCap, false) {}

GamepadDeviceLinux::~GamepadDeviceLinux() = default;

void GamepadDeviceLinux::DoShutdown() {
  CloseJoydevNode();
  CloseEvdevNode();
  CloseHidrawNode();
}

bool GamepadDeviceLinux::IsEmpty() const {
  return joydev_fd_ < 0 && evdev_fd_ < 0 && hidraw_fd_ < 0;
}

bool GamepadDeviceLinux::SupportsVibration() const {
  if (dualshock4_ || hid_haptics_)
    return true;

  // Vibration is only supported over USB.
  // TODO(mattreynolds): add support for Switch Pro vibration over Bluetooth.
  if (switch_pro_)
    return bus_type_ == GAMEPAD_BUS_USB;

  return supports_force_feedback_ && evdev_fd_ >= 0;
}

void GamepadDeviceLinux::ReadPadState(Gamepad* pad) {
  if (switch_pro_ && bus_type_ == GAMEPAD_BUS_USB) {
    // When connected over USB, the Switch Pro controller does not correctly
    // report its state over USB HID. Instead, fetch the state using the
    // device's vendor-specific USB protocol.
    switch_pro_->ReadUsbPadState(pad);
    return;
  }

  DCHECK_GE(joydev_fd_, 0);

  // Read button and axis events from the joydev device.
  bool pad_updated = ReadJoydevState(pad);

  // Evdev special buttons must be initialized after we have read from joydev
  // at least once to ensure we do not assign a button index already in use by
  // joydev.
  if (!evdev_special_keys_initialized_)
    InitializeEvdevSpecialKeys();

  // Read button events from the evdev device.
  if (!special_button_map_.empty()) {
    if (ReadEvdevSpecialKeys(pad))
      pad_updated = true;
  }

  if (pad_updated)
    pad->timestamp = GamepadDataFetcher::CurrentTimeInMicroseconds();
}

bool GamepadDeviceLinux::ReadJoydevState(Gamepad* pad) {
  DCHECK(pad);

  if (joydev_fd_ < 0)
    return false;

  // Read button and axis events from the joydev device.
  bool pad_updated = false;
  js_event event;
  while (HANDLE_EINTR(read(joydev_fd_, &event, sizeof(struct js_event))) > 0) {
    size_t item = event.number;
    if (event.type & JS_EVENT_AXIS) {
      if (item >= Gamepad::kAxesLengthCap)
        continue;

      pad->axes[item] = event.value / kMaxLinuxAxisValue;

      if (item >= pad->axes_length)
        pad->axes_length = item + 1;
      pad_updated = true;
    } else if (event.type & JS_EVENT_BUTTON) {
      if (item >= Gamepad::kButtonsLengthCap)
        continue;

      pad->buttons[item].pressed = event.value;
      pad->buttons[item].value = event.value ? 1.0 : 0.0;

      // When a joydev device is opened, synthetic events are generated for
      // each joystick button and axis with the JS_EVENT_INIT flag set on the
      // event type. Use this signal to mark these button indices as used.
      if (event.type & JS_EVENT_INIT)
        button_indices_used_[item] = true;

      if (item >= pad->buttons_length)
        pad->buttons_length = item + 1;
      pad_updated = true;
    }
  }
  return pad_updated;
}

void GamepadDeviceLinux::InitializeEvdevSpecialKeys() {
  if (evdev_fd_ < 0)
    return;

  // Do some one-time initialization to decide indices for the evdev special
  // buttons.
  evdev_special_keys_initialized_ = true;
  std::vector<bool> special_key_present;
  size_t unmapped_button_count =
      CheckSpecialKeys(evdev_fd_, &special_key_present);

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

      // Advance to the next unused button index.
      while (button_indices_used_[button_index] &&
             button_index < Gamepad::kButtonsLengthCap) {
        ++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;
    }
  }
}

bool GamepadDeviceLinux::ReadEvdevSpecialKeys(Gamepad* pad) {
  DCHECK(pad);

  if (evdev_fd_ < 0)
    return false;

  // Read special button events through evdev.
  bool pad_updated = false;
  input_event ev;
  ssize_t bytes_read;
  while ((bytes_read =
              HANDLE_EINTR(read(evdev_fd_, &ev, sizeof(input_event)))) > 0) {
    if (size_t{bytes_read} < sizeof(input_event))
      break;
    if (ev.type != EV_KEY)
      continue;

    for (size_t special_index = 0; special_index < kSpecialKeysLen;
         ++special_index) {
      int button_index = special_button_map_[special_index];
      if (button_index < 0)
        continue;
      if (ev.code == kSpecialKeys[special_index]) {
        pad->buttons[button_index].pressed = ev.value;
        pad->buttons[button_index].value = ev.value ? 1.0 : 0.0;
        pad_updated = true;
      }
    }
  }

  return pad_updated;
}

GamepadStandardMappingFunction GamepadDeviceLinux::GetMappingFunction() const {
  return GetGamepadStandardMappingFunction(vendor_id_, product_id_,
                                           version_number_, bus_type_);
}

bool GamepadDeviceLinux::IsSameDevice(const UdevGamepadLinux& pad_info) {
  return pad_info.syspath_prefix == syspath_prefix_;
}

bool GamepadDeviceLinux::OpenJoydevNode(const UdevGamepadLinux& pad_info,
                                        udev_device* device) {
  DCHECK(pad_info.type == UdevGamepadLinux::Type::JOYDEV);
  DCHECK(pad_info.syspath_prefix == syspath_prefix_);

  CloseJoydevNode();
  joydev_fd_ = open(pad_info.path.c_str(), O_RDONLY | O_NONBLOCK);
  if (joydev_fd_ < 0)
    return false;

  udev_device* parent_device =
      device::udev_device_get_parent_with_subsystem_devtype(
          device, kInputSubsystem, nullptr);

  const char* vendor_id =
      udev_device_get_sysattr_value(parent_device, "id/vendor");
  const char* product_id =
      udev_device_get_sysattr_value(parent_device, "id/product");
  const char* version_number =
      udev_device_get_sysattr_value(parent_device, "id/version");
  const char* name = udev_device_get_sysattr_value(parent_device, "name");
  std::string name_string(name ? name : "");

  uint16_t vendor_id_int = HexStringToUInt16WithDefault(vendor_id, 0);
  uint16_t product_id_int = HexStringToUInt16WithDefault(product_id, 0);
  uint16_t version_number_int = HexStringToUInt16WithDefault(version_number, 0);

  // In many cases the information the input subsystem contains isn't
  // as good as the information that the device bus has, walk up further
  // to the subsystem/device type "usb"/"usb_device" and if this device
  // has the same vendor/product id, prefer the description from that.
  struct udev_device* usb_device =
      udev_device_get_parent_with_subsystem_devtype(
          parent_device, kUsbSubsystem, kUsbDeviceType);
  if (usb_device) {
    const char* usb_vendor_id =
        udev_device_get_sysattr_value(usb_device, "idVendor");
    const char* usb_product_id =
        udev_device_get_sysattr_value(usb_device, "idProduct");

    if (vendor_id && product_id && strcmp(vendor_id, usb_vendor_id) == 0 &&
        strcmp(product_id, usb_product_id) == 0) {
      const char* manufacturer =
          udev_device_get_sysattr_value(usb_device, "manufacturer");
      const char* product =
          udev_device_get_sysattr_value(usb_device, "product");

      // Replace the previous name string with one containing the better
      // information.
      name_string = base::StringPrintf("%s %s", manufacturer, product);
    }
  }

  joydev_index_ = pad_info.index;
  vendor_id_ = vendor_id_int;
  product_id_ = product_id_int;
  version_number_ = version_number_int;
  name_ = name_string;

  return true;
}

void GamepadDeviceLinux::CloseJoydevNode() {
  if (joydev_fd_ >= 0) {
    close(joydev_fd_);
    joydev_fd_ = -1;
  }
  joydev_index_ = -1;
  vendor_id_ = 0;
  product_id_ = 0;
  version_number_ = 0;
  name_.clear();

  // Button indices must be recomputed once the joydev node is closed.
  button_indices_used_.clear();
  special_button_map_.clear();
  evdev_special_keys_initialized_ = false;
}

bool GamepadDeviceLinux::OpenEvdevNode(const UdevGamepadLinux& pad_info) {
  DCHECK(pad_info.type == UdevGamepadLinux::Type::EVDEV);
  DCHECK(pad_info.syspath_prefix == syspath_prefix_);

  CloseEvdevNode();
  evdev_fd_ = open(pad_info.path.c_str(), O_RDWR | O_NONBLOCK);
  if (evdev_fd_ < 0)
    return false;

  supports_force_feedback_ = HasRumbleCapability(evdev_fd_);
  bus_type_ = GetEvdevBusType(evdev_fd_);

  return true;
}

void GamepadDeviceLinux::CloseEvdevNode() {
  if (evdev_fd_ >= 0) {
    if (effect_id_ != kInvalidEffectId) {
      DestroyEffect(evdev_fd_, effect_id_);
      effect_id_ = kInvalidEffectId;
    }
    close(evdev_fd_);
    evdev_fd_ = -1;
  }
  supports_force_feedback_ = false;

  // Clear any entries in |button_indices_used_| that were taken by evdev.
  if (!special_button_map_.empty()) {
    for (int button_index : special_button_map_) {
      if (button_index >= 0)
        button_indices_used_[button_index] = false;
    }
  }
  special_button_map_.clear();
  evdev_special_keys_initialized_ = false;
}

bool GamepadDeviceLinux::OpenHidrawNode(const UdevGamepadLinux& pad_info) {
  DCHECK(pad_info.type == UdevGamepadLinux::Type::HIDRAW);
  DCHECK(pad_info.syspath_prefix == syspath_prefix_);

  CloseHidrawNode();
  hidraw_fd_ = open(pad_info.path.c_str(), O_RDWR | O_NONBLOCK);
  if (hidraw_fd_ < 0)
    return false;

  uint16_t vendor_id;
  uint16_t product_id;
  bool is_dualshock4 = false;
  bool is_switch_pro = false;
  bool is_hid_haptic = false;
  if (GetHidrawDevinfo(hidraw_fd_, &bus_type_, &vendor_id, &product_id)) {
    is_dualshock4 =
        Dualshock4ControllerLinux::IsDualshock4(vendor_id, product_id);
    is_switch_pro =
        SwitchProControllerLinux::IsSwitchPro(vendor_id, product_id);
    is_hid_haptic = HidHapticGamepadLinux::IsHidHaptic(vendor_id, product_id);
    DCHECK_LE(is_dualshock4 + is_switch_pro + is_hid_haptic, 1);
  }

  if (is_dualshock4 && !dualshock4_)
    dualshock4_ = std::make_unique<Dualshock4ControllerLinux>(hidraw_fd_);

  if (is_switch_pro && !switch_pro_) {
    switch_pro_ = std::make_unique<SwitchProControllerLinux>(hidraw_fd_);

    if (bus_type_ == GAMEPAD_BUS_USB)
      switch_pro_->SendConnectionStatusQuery();
  }

  if (is_hid_haptic && !hid_haptics_) {
    hid_haptics_ =
        HidHapticGamepadLinux::Create(vendor_id, product_id, hidraw_fd_);
  }

  return true;
}

void GamepadDeviceLinux::CloseHidrawNode() {
  if (dualshock4_)
    dualshock4_->Shutdown();
  dualshock4_.reset();
  if (switch_pro_)
    switch_pro_->Shutdown();
  switch_pro_.reset();
  if (hid_haptics_)
    hid_haptics_->Shutdown();
  hid_haptics_.reset();
  if (hidraw_fd_ >= 0) {
    close(hidraw_fd_);
    hidraw_fd_ = -1;
  }
}

void GamepadDeviceLinux::SetVibration(double strong_magnitude,
                                      double weak_magnitude) {
  if (dualshock4_) {
    dualshock4_->SetVibration(strong_magnitude, weak_magnitude);
    return;
  }

  if (switch_pro_) {
    switch_pro_->SetVibration(strong_magnitude, weak_magnitude);
    return;
  }

  if (hid_haptics_) {
    hid_haptics_->SetVibration(strong_magnitude, weak_magnitude);
    return;
  }

  uint16_t strong_magnitude_scaled =
      static_cast<uint16_t>(strong_magnitude * kRumbleMagnitudeMax);
  uint16_t weak_magnitude_scaled =
      static_cast<uint16_t>(weak_magnitude * kRumbleMagnitudeMax);

  // AbstractHapticGamepad will call SetZeroVibration when the effect is
  // complete, so we don't need to set the duration here except to make sure it
  // is at least as long as the maximum duration.
  uint16_t duration_millis =
      static_cast<uint16_t>(GamepadHapticActuator::kMaxEffectDurationMillis);

  // Upload the effect and get the new effect ID. If we already created an
  // effect on this device, reuse its ID.
  effect_id_ =
      StoreRumbleEffect(evdev_fd_, effect_id_, duration_millis, 0,
                        strong_magnitude_scaled, weak_magnitude_scaled);

  if (effect_id_ != kInvalidEffectId)
    StartOrStopEffect(evdev_fd_, effect_id_, true);
}

void GamepadDeviceLinux::SetZeroVibration() {
  if (dualshock4_) {
    dualshock4_->SetZeroVibration();
    return;
  }

  if (switch_pro_) {
    switch_pro_->SetZeroVibration();
    return;
  }

  if (hid_haptics_) {
    hid_haptics_->SetZeroVibration();
    return;
  }

  if (effect_id_ != kInvalidEffectId)
    StartOrStopEffect(evdev_fd_, effect_id_, false);
}

}  // namespace device
