// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/linux/dev_input/dev_input.h"

#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>

#include <algorithm>
#include <cmath>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "starboard/common/log.h"
#include "starboard/common/once.h"
#include "starboard/common/string.h"
#include "starboard/configuration.h"
#include "starboard/configuration_constants.h"
#include "starboard/directory.h"
#include "starboard/input.h"
#include "starboard/key.h"
#include "starboard/memory.h"
#include "starboard/shared/posix/handle_eintr.h"

namespace starboard {
namespace shared {
namespace dev_input {
namespace {

using ::starboard::shared::starboard::Application;

typedef int FileDescriptor;
const FileDescriptor kInvalidFd = -ENODEV;

enum InputDeviceIds {
  kKeyboardDeviceId = 1,
  kGamepadDeviceId,
};

enum TouchPadPositionState {
  kTouchPadPositionNone = 0,
  kTouchPadPositionX = 1,
  kTouchPadPositionY = 2,
  kTouchPadPositionAll = kTouchPadPositionX | kTouchPadPositionY
};

class ControllerTuning {
 public:
  ~ControllerTuning() {}

  uint16_t GetKeyCode(uint16_t from);
  void MapKeyCode(uint16_t from, uint16_t to) { key_map_[from] = to; }

  float GetMinimumFlat() { return minimum_flat_; }
  void SetMinimumFlat(float value) { minimum_flat_ = value; }

 protected:
  // Only create this object from DeviceMap::CreateControllerTuning()
  ControllerTuning() {}

 private:
  std::unordered_map<int, int> key_map_;
  float minimum_flat_ = 0;

  friend class DeviceMap;
};

uint16_t ControllerTuning::GetKeyCode(uint16_t from) {
  auto mapped_code = key_map_.find(from);
  if (mapped_code != key_map_.end()) {
    return mapped_code->second;
  }
  return from;
}

class DeviceMap {
 public:
  DeviceMap();
  ~DeviceMap() = delete;

  // Gets the singleton instance of the default DeviceMap. This
  // is created the first time it is used.
  static DeviceMap* Get();

  // Return the controller tuning object for a given device. Return null if none
  // is registered.
  ControllerTuning* GetControllerTuning(const std::string& device) const;

 private:
  // Create a controllertuning object.
  ControllerTuning* CreateControllerTuning();

  // Register a controller tuning object for a given device.
  void RegisterControllerTuning(const std::string& device,
                                ControllerTuning* tuning);

  std::unordered_map<std::string, ControllerTuning*> device_map_;

  // Registry for all known controller tunings.
  std::vector<std::unique_ptr<ControllerTuning>> controller_tunings_;
};

DeviceMap::DeviceMap() {
  // Add key mappings for the Xbox controllers.
  ControllerTuning* xbox_one_controller = CreateControllerTuning();
  RegisterControllerTuning("Microsoft X-Box One S pad", xbox_one_controller);
  RegisterControllerTuning("Microsoft X-Box One pad", xbox_one_controller);
  RegisterControllerTuning("Microsoft X-Box 360 pad", xbox_one_controller);
  xbox_one_controller->SetMinimumFlat(0.125);
  xbox_one_controller->MapKeyCode(BTN_NORTH, BTN_WEST);  // Map for 'X'
  xbox_one_controller->MapKeyCode(BTN_WEST, BTN_NORTH);  // Map for 'Y'
  xbox_one_controller->MapKeyCode(BTN_TL, BTN_TL2);      // Map for left bumper.
  xbox_one_controller->MapKeyCode(BTN_TR, BTN_TR2);  // Map for right bumper.

  // Add key mappings for the PlayStation 4 controller.
  ControllerTuning* ps4_controller = CreateControllerTuning();
  RegisterControllerTuning("Sony Interactive Entertainment Wireless Controller",
                           ps4_controller);
  RegisterControllerTuning("Sony Computer Entertainment Wireless Controller",
                           ps4_controller);
  RegisterControllerTuning("Sony PLAYSTATION(R)3 Controller", ps4_controller);

  ps4_controller->MapKeyCode(BTN_TL2, BTN_TL);  // Map for left trigger.
  ps4_controller->MapKeyCode(BTN_TR2, BTN_TR);  // Map for right trigger.
  ps4_controller->MapKeyCode(BTN_TL, BTN_TL2);  // Map for left bumper.
  ps4_controller->MapKeyCode(BTN_TR, BTN_TR2);  // Map for right bumper.

  // Add key mappings for the Horipad Switch wired controller.
  ControllerTuning* switch_controller = CreateControllerTuning();
  RegisterControllerTuning("HORI CO.,LTD. HORIPAD S", switch_controller);

  switch_controller->MapKeyCode(BTN_C, BTN_SOUTH);     // Map for 'A'.
  switch_controller->MapKeyCode(BTN_A, BTN_NORTH);     // Map for 'Y'.
  switch_controller->MapKeyCode(BTN_NORTH, BTN_WEST);  // Map for 'X'.
  switch_controller->MapKeyCode(BTN_WEST, BTN_TL2);    // Map for left bumper.
  switch_controller->MapKeyCode(BTN_Z, BTN_TR2);       // Map for right bumper.

  switch_controller->MapKeyCode(BTN_THUMBL, BTN_SELECT);  // Map for 'capture'.
  switch_controller->MapKeyCode(BTN_MODE, KEY_HOME);      // Map for 'home'.

  switch_controller->MapKeyCode(BTN_TL2, KEY_KPMINUS);  // Map for '-'.
  switch_controller->MapKeyCode(BTN_TR2, KEY_KPPLUS);   // Map for '+'.

  switch_controller->MapKeyCode(BTN_SELECT, BTN_THUMBL);  // Map for left hat.
  switch_controller->MapKeyCode(BTN_START, BTN_THUMBR);   // Map for right hat.
}

void DeviceMap::RegisterControllerTuning(const std::string& device,
                                         ControllerTuning* tuning) {
  SB_DCHECK(GetControllerTuning(device) == NULL ||
            GetControllerTuning(device) == tuning);
  device_map_[device] = tuning;
}

ControllerTuning* DeviceMap::CreateControllerTuning() {
  ControllerTuning* tuning = new ControllerTuning();
  controller_tunings_.emplace_back(tuning);
  return tuning;
}

ControllerTuning* DeviceMap::GetControllerTuning(
    const std::string& device) const {
  auto mapped_device = device_map_.find(device);
  if (mapped_device != device_map_.end()) {
    return mapped_device->second;
  }
  return NULL;
}

SB_ONCE_INITIALIZE_FUNCTION(DeviceMap, GetDeviceMap);

DeviceMap* DeviceMap::Get() {
  DeviceMap* device_map = GetDeviceMap();
  return device_map;
}

struct InputDeviceInfo {
  InputDeviceInfo() : fd(-1), touchpad_position_state(kTouchPadPositionNone) {}

  // Device Name
  std::string name;

  // File descriptor open for the device
  FileDescriptor fd;
  // Absolute Axis info.
  std::map<int, struct input_absinfo> axis_info;
  std::map<int, float> axis_value;
  int touchpad_position_state;
  ControllerTuning* tuning;
};

bool IsTouchpadPositionKnown(InputDeviceInfo* device_info) {
  return device_info->touchpad_position_state == kTouchPadPositionAll;
}

// Private implementation of DevInput.
class DevInputImpl : public DevInput {
 public:
  explicit DevInputImpl(SbWindow window);
  DevInputImpl(SbWindow window, FileDescriptor wake_up_fd);
  ~DevInputImpl() override;

  void InitDevInputImpl(SbWindow window);

  Event* PollNextSystemEvent() override;
  Event* WaitForSystemEventWithTimeout(int64_t time) override;
  void WakeSystemEventWait() override;

 private:
  // Converts an input_event into a kSbEventInput Application::Event. The caller
  // is responsible for deleting the returned event.
  Event* InputToApplicationEvent(const struct input_event& event,
                                 int modifiers,
                                 InputDeviceInfo* device_info);

  // Converts an input_event containing a key input into a kSbEventInput
  // Application::Event. The caller is responsible for deleting the returned
  // event.
  Event* KeyInputToApplicationEvent(const struct input_event& event,
                                    int modifiers,
                                    InputDeviceInfo* device_info);

  // Converts an input_event containing an axis event into a kSbEventInput
  // Application::Event. The caller is responsible for deleting the returned
  // event.
  Event* AxisInputToApplicationEvent(const struct input_event& event,
                                     int modifiers,
                                     InputDeviceInfo* device_info);

  // The window to attribute /dev/input events to.
  SbWindow window_;

  // A set of read-only file descriptor of keyboard input devices.
  std::vector<InputDeviceInfo> input_devices_;

  // A file descriptor of the write end of a pipe that can be written to from
  // any thread to wake up this waiter in a thread-safe manner.
  FileDescriptor wakeup_write_fd_;

  // A file descriptor of the read end of a pipe that this waiter will wait on
  // to allow it to be signalled safely from other threads.
  FileDescriptor wakeup_read_fd_;

  FileDescriptor wake_up_fd_;
};

// Helper class to manage a file descriptor set.
class FdSet {
 public:
  FdSet() : max_fd_(kInvalidFd) { FD_ZERO(&set_); }

  void Set(FileDescriptor fd) {
    FD_SET(fd, &set_);
    if (fd > max_fd_) {
      max_fd_ = fd;
    }
  }

  bool IsSet(FileDescriptor fd) { return FD_ISSET(fd, &set_); }

  fd_set* set() { return &set_; }
  FileDescriptor max_fd() { return max_fd_; }

 private:
  fd_set set_;
  FileDescriptor max_fd_;
};

// Converts an input_event code into an SbKey.
SbKey KeyCodeToSbKey(uint16_t code) {
  switch (code) {
    case KEY_BACKSPACE:
      return kSbKeyBack;
    case KEY_DELETE:
      return kSbKeyDelete;
    case KEY_TAB:
      return kSbKeyTab;
    case KEY_LINEFEED:
    case KEY_ENTER:
    case KEY_KPENTER:
      return kSbKeyReturn;
    case KEY_CLEAR:
      return kSbKeyClear;
    case KEY_SPACE:
      return kSbKeySpace;
    case KEY_HOME:
      return kSbKeyHome;
    case KEY_END:
      return kSbKeyEnd;
    case KEY_PAGEUP:
      return kSbKeyPrior;
    case KEY_PAGEDOWN:
      return kSbKeyNext;
    case KEY_LEFT:
      return kSbKeyLeft;
    case KEY_RIGHT:
      return kSbKeyRight;
    case KEY_DOWN:
      return kSbKeyDown;
    case KEY_UP:
      return kSbKeyUp;
    case KEY_ESC:
      return kSbKeyEscape;
    case KEY_KATAKANA:
    case KEY_HIRAGANA:
    case KEY_KATAKANAHIRAGANA:
      return kSbKeyKana;
    case KEY_HANGEUL:
      return kSbKeyHangul;
    case KEY_HANJA:
      return kSbKeyHanja;
    case KEY_HENKAN:
      return kSbKeyConvert;
    case KEY_MUHENKAN:
      return kSbKeyNonconvert;
    case KEY_ZENKAKUHANKAKU:
      return kSbKeyDbeDbcschar;
    case KEY_A:
      return kSbKeyA;
    case KEY_B:
      return kSbKeyB;
    case KEY_C:
      return kSbKeyC;
    case KEY_D:
      return kSbKeyD;
    case KEY_E:
      return kSbKeyE;
    case KEY_F:
      return kSbKeyF;
    case KEY_G:
      return kSbKeyG;
    case KEY_H:
      return kSbKeyH;
    case KEY_I:
      return kSbKeyI;
    case KEY_J:
      return kSbKeyJ;
    case KEY_K:
      return kSbKeyK;
    case KEY_L:
      return kSbKeyL;
    case KEY_M:
      return kSbKeyM;
    case KEY_N:
      return kSbKeyN;
    case KEY_O:
      return kSbKeyO;
    case KEY_P:
      return kSbKeyP;
    case KEY_Q:
      return kSbKeyQ;
    case KEY_R:
      return kSbKeyR;
    case KEY_S:
      return kSbKeyS;
    case KEY_T:
      return kSbKeyT;
    case KEY_U:
      return kSbKeyU;
    case KEY_V:
      return kSbKeyV;
    case KEY_W:
      return kSbKeyW;
    case KEY_X:
      return kSbKeyX;
    case KEY_Y:
      return kSbKeyY;
    case KEY_Z:
      return kSbKeyZ;

    case KEY_0:
      return kSbKey0;
    case KEY_1:
      return kSbKey1;
    case KEY_2:
      return kSbKey2;
    case KEY_3:
      return kSbKey3;
    case KEY_4:
      return kSbKey4;
    case KEY_5:
      return kSbKey5;
    case KEY_6:
      return kSbKey6;
    case KEY_7:
      return kSbKey7;
    case KEY_8:
      return kSbKey8;
    case KEY_9:
      return kSbKey9;

    case KEY_NUMERIC_0:
    case KEY_NUMERIC_1:
    case KEY_NUMERIC_2:
    case KEY_NUMERIC_3:
    case KEY_NUMERIC_4:
    case KEY_NUMERIC_5:
    case KEY_NUMERIC_6:
    case KEY_NUMERIC_7:
    case KEY_NUMERIC_8:
    case KEY_NUMERIC_9:
      return static_cast<SbKey>(kSbKey0 + (code - KEY_NUMERIC_0));

    case KEY_KP0:
      return kSbKeyNumpad0;
    case KEY_KP1:
      return kSbKeyNumpad1;
    case KEY_KP2:
      return kSbKeyNumpad2;
    case KEY_KP3:
      return kSbKeyNumpad3;
    case KEY_KP4:
      return kSbKeyNumpad4;
    case KEY_KP5:
      return kSbKeyNumpad5;
    case KEY_KP6:
      return kSbKeyNumpad6;
    case KEY_KP7:
      return kSbKeyNumpad7;
    case KEY_KP8:
      return kSbKeyNumpad8;
    case KEY_KP9:
      return kSbKeyNumpad9;

    case KEY_KPASTERISK:
      return kSbKeyMultiply;
    case KEY_KPDOT:
      return kSbKeyDecimal;
    case KEY_KPSLASH:
      return kSbKeyDivide;
    case KEY_KPPLUS:
    case KEY_EQUAL:
      return kSbKeyOemPlus;
    case KEY_COMMA:
      return kSbKeyOemComma;
    case KEY_KPMINUS:
    case KEY_MINUS:
      return kSbKeyOemMinus;
    case KEY_DOT:
      return kSbKeyOemPeriod;
    case KEY_SEMICOLON:
      return kSbKeyOem1;
    case KEY_SLASH:
      return kSbKeyOem2;
    case KEY_GRAVE:
      return kSbKeyOem3;
    case KEY_LEFTBRACE:
      return kSbKeyOem4;
    case KEY_BACKSLASH:
      return kSbKeyOem5;
    case KEY_RIGHTBRACE:
      return kSbKeyOem6;
    case KEY_APOSTROPHE:
      return kSbKeyOem7;
    case KEY_LEFTSHIFT:
    case KEY_RIGHTSHIFT:
      return kSbKeyShift;
    case KEY_LEFTCTRL:
    case KEY_RIGHTCTRL:
      return kSbKeyControl;
    case KEY_LEFTMETA:
    case KEY_RIGHTMETA:
    case KEY_LEFTALT:
    case KEY_RIGHTALT:
      return kSbKeyMenu;
    case KEY_PAUSE:
      return kSbKeyPause;
    case KEY_CAPSLOCK:
      return kSbKeyCapital;
    case KEY_NUMLOCK:
      return kSbKeyNumlock;
    case KEY_SCROLLLOCK:
      return kSbKeyScroll;
    case KEY_SELECT:
      return kSbKeySelect;
    case KEY_PRINT:
      return kSbKeyPrint;
    case KEY_INSERT:
      return kSbKeyInsert;
    case KEY_HELP:
      return kSbKeyHelp;
    case KEY_MENU:
      return kSbKeyApps;
    case KEY_FN_F1:
    case KEY_FN_F2:
    case KEY_FN_F3:
    case KEY_FN_F4:
    case KEY_FN_F5:
    case KEY_FN_F6:
    case KEY_FN_F7:
    case KEY_FN_F8:
    case KEY_FN_F9:
    case KEY_FN_F10:
    case KEY_FN_F11:
    case KEY_FN_F12:
      return static_cast<SbKey>(kSbKeyF1 + (code - KEY_FN_F1));

    // For supporting multimedia buttons on a USB keyboard.
    case KEY_BACK:
      return kSbKeyBrowserBack;
    case KEY_FORWARD:
      return kSbKeyBrowserForward;
    case KEY_REFRESH:
      return kSbKeyBrowserRefresh;
    case KEY_STOP:
      return kSbKeyBrowserStop;
    case KEY_SEARCH:
      return kSbKeyBrowserSearch;
    case KEY_FAVORITES:
      return kSbKeyBrowserFavorites;
    case KEY_HOMEPAGE:
      return kSbKeyBrowserHome;
    case KEY_MUTE:
      return kSbKeyVolumeMute;
    case KEY_VOLUMEDOWN:
      return kSbKeyVolumeDown;
    case KEY_VOLUMEUP:
      return kSbKeyVolumeUp;
    case KEY_NEXTSONG:
      return kSbKeyMediaNextTrack;
    case KEY_PREVIOUSSONG:
      return kSbKeyMediaPrevTrack;
    case KEY_STOPCD:
      return kSbKeyMediaStop;
    case KEY_PLAYPAUSE:
      return kSbKeyMediaPlayPause;
    case KEY_MAIL:
      return kSbKeyMediaLaunchMail;
    case KEY_CALC:
      return kSbKeyMediaLaunchApp2;
    case KEY_WLAN:
      return kSbKeyWlan;
    case KEY_POWER:
      return kSbKeyPower;
    case KEY_BRIGHTNESSDOWN:
      return kSbKeyBrightnessDown;
    case KEY_BRIGHTNESSUP:
      return kSbKeyBrightnessUp;

    // Gamepad buttons.
    //   https://www.kernel.org/doc/Documentation/input/gamepad.txt
    case BTN_TL:
      return kSbKeyGamepadLeftTrigger;
    case BTN_TR:
      return kSbKeyGamepadRightTrigger;
    case BTN_DPAD_DOWN:
      return kSbKeyGamepadDPadDown;
    case BTN_DPAD_UP:
      return kSbKeyGamepadDPadUp;
    case BTN_DPAD_LEFT:
      return kSbKeyGamepadDPadLeft;
    case BTN_DPAD_RIGHT:
      return kSbKeyGamepadDPadRight;
    case BTN_TL2:
      return kSbKeyGamepadLeftBumper;
    case BTN_TR2:
      return kSbKeyGamepadRightBumper;
    case BTN_SOUTH:
      return kSbKeyGamepad1;
    case BTN_EAST:
      return kSbKeyGamepad2;
    case BTN_WEST:
      return kSbKeyGamepad3;
    case BTN_NORTH:
      return kSbKeyGamepad4;
    case BTN_SELECT:
      return kSbKeyGamepad5;
    case BTN_START:
      return kSbKeyGamepad6;
    case BTN_MODE:
      return kSbKeyGamepadSystem;
    case BTN_THUMBL:
      return kSbKeyGamepadLeftStick;
    case BTN_THUMBR:
      return kSbKeyGamepadRightStick;
  }
  SB_DLOG(WARNING) << "Unknown code: 0x" << std::hex << code;
  return kSbKeyUnknown;
}  // NOLINT(readability/fn_size)

// Get a SbKeyLocation from an input_event.code.
SbKeyLocation KeyCodeToSbKeyLocation(uint16_t code) {
  switch (code) {
    case KEY_LEFTALT:
    case KEY_LEFTCTRL:
    case KEY_LEFTMETA:
    case KEY_LEFTSHIFT:
      return kSbKeyLocationLeft;
    case KEY_RIGHTALT:
    case KEY_RIGHTCTRL:
    case KEY_RIGHTMETA:
    case KEY_RIGHTSHIFT:
      return kSbKeyLocationRight;
  }

  return kSbKeyLocationUnspecified;
}

// Returns the number of bytes needed to represent a bit set
// of |bit_count| size.
int BytesNeededForBitSet(int bit_count) {
  return (bit_count + 7) / 8;
}

// Returns true if |bit| is set in |bitset|.
bool IsBitSet(const std::vector<uint8_t>& bitset, int bit) {
  return !!(bitset.at(bit / 8) & (1 << (bit % 8)));
}

bool IsAxisFlat(int minimum_flat,
                float rest_value,
                const struct input_absinfo& axis_info) {
  SB_DCHECK((axis_info.flat * 2) <= (axis_info.maximum - axis_info.minimum));
  int flat = std::max(minimum_flat, axis_info.flat);
  return (flat != 0) && (axis_info.value > rest_value - flat) &&
         (axis_info.value < rest_value + flat);
}

float GetAxisValue(bool is_trigger,
                   float minimum_flat,
                   const struct input_absinfo& axis_info) {
  float median =
      static_cast<float>(axis_info.maximum + axis_info.minimum) / 2.0f;
  float range = static_cast<float>(axis_info.maximum - axis_info.minimum);
  float radius = range / 2.0f;
  if (IsAxisFlat(minimum_flat * radius, is_trigger ? axis_info.minimum : median,
                 axis_info)) {
    return is_trigger ? -1 : 0;
  }
  // Scale the axis value to [-1, 1].
  float axis_value = (static_cast<float>(axis_info.value) - median) / radius;

  if (axis_info.flat != 0) {
    // Calculate the flat value scaled to [0, 1].
    float flat = static_cast<float>(axis_info.flat) / range;

    int sign = axis_value < 0.0f ? -1 : 1;
    // Rescale the range:
    // [-1.0f, -flat] to [-1.0f, 0.0f] and [flat, 1.0f] to [0.0f, 1.0f].
    axis_value = (axis_value - sign * flat) / (1 - flat);
  }
  return axis_value;
}

void GetInputDeviceAbsoluteAxisInfo(int axis,
                                    const std::vector<uint8_t>& bits,
                                    InputDeviceInfo* info) {
  if (IsBitSet(bits, axis)) {
    struct input_absinfo axis_info;
    int result = ioctl(info->fd, EVIOCGABS(axis), &axis_info);
    if (result < 0) {
      return;
    }
    info->axis_info.insert(std::make_pair(axis, axis_info));
    bool is_trigger = axis == ABS_Z || axis == ABS_RZ;
    info->axis_value.insert(std::make_pair(
        axis,
        GetAxisValue(is_trigger, info->tuning->GetMinimumFlat(), axis_info)));
  }
}

void GetInputDeviceInfo(InputDeviceInfo* info) {
  char device_name[1024];
  if (ioctl(info->fd, EVIOCGNAME(sizeof(device_name)), device_name) >= 0) {
    size_t length = strnlen(device_name, sizeof(device_name));
    info->name.assign(device_name, length);
  }

  info->tuning = DeviceMap::Get()->GetControllerTuning(info->name);

  std::vector<uint8_t> axis_bits(BytesNeededForBitSet(KEY_MAX));
  int result =
      ioctl(info->fd, EVIOCGBIT(EV_ABS, axis_bits.size()), axis_bits.data());
  if (result < 0) {
    return;
  }

  GetInputDeviceAbsoluteAxisInfo(ABS_X, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_Y, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_Z, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_RZ, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_RX, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_RY, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_HAT0X, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_HAT0Y, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_MT_POSITION_X, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_MT_POSITION_Y, axis_bits, info);
  GetInputDeviceAbsoluteAxisInfo(ABS_MT_TRACKING_ID, axis_bits, info);
  // TODO: Handle multi-touch using ABS_MT_SLOT.
}

FileDescriptor OpenDeviceIfKeyboardOrGamepad(const char* path) {
  FileDescriptor fd = open(path, O_RDONLY | O_NONBLOCK);
  if (fd < 0) {
    // Open can fail if the application doesn't have permission to access
    // the input device directly.
    return kInvalidFd;
  }

  std::vector<uint8_t> ev_bits(BytesNeededForBitSet(EV_CNT));
  std::vector<uint8_t> key_bits(BytesNeededForBitSet(KEY_MAX));

  int result = ioctl(fd, EVIOCGBIT(0, ev_bits.size()), ev_bits.data());
  if (result < 0) {
    close(fd);
    return kInvalidFd;
  }

  bool has_ev_key = IsBitSet(ev_bits, EV_KEY);
  if (!has_ev_key) {
    close(fd);
    return kInvalidFd;
  }

  result = ioctl(fd, EVIOCGBIT(EV_KEY, key_bits.size()), key_bits.data());
  if (result < 0) {
    close(fd);
    return kInvalidFd;
  }

  bool has_key_space = IsBitSet(key_bits, KEY_SPACE);
  bool has_gamepad_button = IsBitSet(key_bits, BTN_GAMEPAD);
  if (!has_key_space && !has_gamepad_button) {
    // If it doesn't have a space key or gamepad button, it may be a mouse.
    close(fd);
    return kInvalidFd;
  }

  result = ioctl(fd, EVIOCGRAB, 1);
  if (result != 0) {
    SB_DLOG(ERROR) << __FUNCTION__ << ": "
                   << "Unable to get exclusive access to \"" << path << "\".";
    close(fd);
    return kInvalidFd;
  }
  return fd;
}

// Searches for the keyboard and game controller /dev/input devices, opens them
// and returns the device info with a file descriptor and absolute axis details.
std::vector<InputDeviceInfo> GetInputDevices() {
  const char kDevicePath[] = "/dev/input";
  SbDirectory directory = SbDirectoryOpen(kDevicePath, NULL);
  std::vector<InputDeviceInfo> input_devices;
  if (!SbDirectoryIsValid(directory)) {
    SB_DLOG(ERROR) << __FUNCTION__ << ": No /dev/input support, "
                   << "unable to open: " << kDevicePath;
    return input_devices;
  }

  while (true) {
    std::vector<char> entry(kSbFileMaxName);

    if (!SbDirectoryGetNext(directory, entry.data(), kSbFileMaxName)) {
      break;
    }

    std::string path = kDevicePath;
    path += "/";
    path += entry.data();

    struct stat file_info;
    if (stat(path.c_str(), &file_info) == 0 && S_ISDIR(file_info.st_mode)) {
      // This is a subdirectory. Skip.
      continue;
    }

    FileDescriptor fd = OpenDeviceIfKeyboardOrGamepad(path.c_str());
    if (fd == kInvalidFd) {
      continue;
    }
    InputDeviceInfo info;
    info.fd = fd;
    GetInputDeviceInfo(&info);

    SB_DCHECK(info.fd != kInvalidFd);
    input_devices.push_back(info);
  }

  SbDirectoryClose(directory);
  return input_devices;
}

// Returns whether |key_code|'s bit is set in the bitmap |map|, assuming
// |key_code| fits into |map|.
bool TestKey(int key_code, char* map) {
  return map[key_code / 8] & (1 << (key_code % 8));
}

// Returns whether |key_code|'s bit is set in the bitmap |map|, assuming
// |key_code| fits into |map|.
int GetModifier(int left_key_code,
                int right_key_code,
                SbKeyModifiers modifier,
                char* map) {
  if (TestKey(left_key_code, map) || TestKey(right_key_code, map)) {
    return modifier;
  }

  return 0;
}

// Polls the given input file descriptor for an input_event. If there are no
// bytes available, assumes that there is no input event to read. If it gets a
// partial event, it will assume that it will be completed, and spins until it
// receives an entire event.
bool PollInputEvent(InputDeviceInfo* device_info,
                    struct input_event* out_event,
                    int* out_modifiers) {
  if (device_info->fd == kInvalidFd) {
    return false;
  }

  SB_DCHECK(out_event);
  SB_DCHECK(out_modifiers);

  const size_t kEventSize = sizeof(struct input_event);
  size_t remaining = kEventSize;
  char* buffer = reinterpret_cast<char*>(out_event);
  while (remaining > 0) {
    int bytes_read = read(device_info->fd, buffer, remaining);
    if (bytes_read <= 0) {
      if (errno == EAGAIN || bytes_read == 0) {
        if (remaining == kEventSize) {
          // Normal nothing there case.
          return false;
        }

        // We have a partial read, so keep trying.
        continue;
      }

      // Some unexpected type of read error occurred.
      SB_DLOG(ERROR) << __FUNCTION__ << ": Error reading input: " << errno
                     << " - " << strerror(errno);
      return false;
    }

    SB_DCHECK(bytes_read <= remaining)
        << "bytes_read=" << bytes_read << ", remaining=" << remaining;
    remaining -= bytes_read;
    buffer += bytes_read;
  }

  if ((out_event->type != EV_KEY) && (out_event->type != EV_ABS)) {
    return false;
  }

  // Calculate modifiers.
  int modifiers = 0;
  char map[(KEY_MAX / 8) + 1] = {0};
  errno = 0;
  int result = ioctl(device_info->fd, EVIOCGKEY(sizeof(map)), map);
  if (result != -1) {
    modifiers |=
        GetModifier(KEY_LEFTSHIFT, KEY_RIGHTSHIFT, kSbKeyModifiersShift, map);
    modifiers |=
        GetModifier(KEY_LEFTALT, KEY_RIGHTALT, kSbKeyModifiersAlt, map);
    modifiers |=
        GetModifier(KEY_LEFTCTRL, KEY_RIGHTCTRL, kSbKeyModifiersCtrl, map);
    modifiers |=
        GetModifier(KEY_LEFTMETA, KEY_RIGHTMETA, kSbKeyModifiersMeta, map);
  } else {
    SB_DLOG(ERROR) << __FUNCTION__ << ": Error getting modifiers: " << errno
                   << " - " << strerror(errno);
  }

  *out_modifiers = modifiers;
  return true;
}

// Simple helper to close a FileDescriptor if set, and to set it to kInvalidFd,
// to ensure it doesn't get used after close.
void CloseFdSafely(FileDescriptor* fd) {
  if (*fd != kInvalidFd) {
    close(*fd);
    *fd = kInvalidFd;
  }
}

// Also in starboard/shared/libevent/socket_waiter_internal.cc
// TODO: Consider consolidating.
int SetNonBlocking(FileDescriptor fd) {
  int flags = fcntl(fd, F_GETFL, 0);
  if (flags == -1) {
    flags = 0;
  }
  return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

DevInputImpl::DevInputImpl(SbWindow window)
    : window_(window),
      input_devices_(GetInputDevices()),
      wakeup_write_fd_(kInvalidFd),
      wakeup_read_fd_(kInvalidFd),
      wake_up_fd_(kInvalidFd) {
  InitDevInputImpl(window);
}

DevInputImpl::DevInputImpl(SbWindow window, FileDescriptor wake_up_fd)
    : window_(window),
      input_devices_(GetInputDevices()),
      wakeup_write_fd_(kInvalidFd),
      wakeup_read_fd_(kInvalidFd),
      wake_up_fd_(wake_up_fd) {
  InitDevInputImpl(window);
}

void DevInputImpl::InitDevInputImpl(SbWindow window) {
  // Initialize wakeup pipe.
  FileDescriptor fds[2] = {kInvalidFd, kInvalidFd};
  int result = pipe(fds);
  SB_DCHECK(result == 0) << "result=" << result;

  wakeup_read_fd_ = fds[0];
  SB_DCHECK(wakeup_read_fd_ != kInvalidFd);
  result = SetNonBlocking(wakeup_read_fd_);
  SB_DCHECK(result == 0) << "result=" << result;

  wakeup_write_fd_ = fds[1];
  SB_DCHECK(wakeup_write_fd_ != kInvalidFd);
  result = SetNonBlocking(wakeup_write_fd_);
  SB_DCHECK(result == 0) << "result=" << result;
}

DevInputImpl::~DevInputImpl() {
  for (const auto& device : input_devices_) {
    close(device.fd);
  }
  CloseFdSafely(&wakeup_write_fd_);
  CloseFdSafely(&wakeup_read_fd_);
}

DevInput::Event* DevInputImpl::PollNextSystemEvent() {
  struct input_event event;
  int modifiers = 0;
  for (auto& device : input_devices_) {
    if (!PollInputEvent(&device, &event, &modifiers)) {
      continue;
    }

    return InputToApplicationEvent(event, modifiers, &device);
  }
  return NULL;
}

DevInput::Event* DevInputImpl::WaitForSystemEventWithTimeout(int64_t duration) {
  Event* event = PollNextSystemEvent();
  if (event) {
    return event;
  }

  FdSet read_set;
  if (wake_up_fd_ != kInvalidFd) {
    read_set.Set(wake_up_fd_);
  }

  for (std::vector<InputDeviceInfo>::const_iterator it = input_devices_.begin();
       it != input_devices_.end(); ++it) {
    read_set.Set(it->fd);
  }
  read_set.Set(wakeup_read_fd_);

  int64_t clamped_duration_usec = std::max<int64_t>(duration, 0LL);
  struct timeval tv;
  tv.tv_sec = clamped_duration_usec / 1'000'000;
  tv.tv_usec = clamped_duration_usec % 1'000'000;
  if (select(read_set.max_fd() + 1, read_set.set(), NULL, NULL, &tv) == 0) {
    // This is the timeout case.
    return NULL;
  }

  // We may have been woken up, so let's consume one wakeup, if selected.
  if (read_set.IsSet(wakeup_read_fd_)) {
    char buf;
    int bytes_read = HANDLE_EINTR(read(wakeup_read_fd_, &buf, 1));
    SB_DCHECK(bytes_read == 1);
  }

  return PollNextSystemEvent();
}

void DevInputImpl::WakeSystemEventWait() {
  char buf = 1;
  while (true) {
    int bytes_written = HANDLE_EINTR(write(wakeup_write_fd_, &buf, 1));
    if (bytes_written > 0) {
      SB_DCHECK(bytes_written == 1) << "bytes_written=" << bytes_written;
      return;
    }

    if (errno == EAGAIN) {
      continue;
    }

    SB_DLOG(FATAL) << __FUNCTION__ << ": errno=" << errno << " - "
                   << strerror(errno);
  }
}

namespace {

// Creates a key event for an analog button input.
DevInput::Event* CreateAnalogButtonKeyEvent(SbWindow window,
                                            float axis_value,
                                            float previous_axis_value,
                                            SbKey key,
                                            SbKeyLocation location,
                                            int modifiers,
                                            const struct input_event& event) {
  SbInputEventType previous_type =
      (std::abs(previous_axis_value) > 0.5 ? kSbInputEventTypePress
                                           : kSbInputEventTypeUnpress);
  SbInputEventType type =
      (std::abs(axis_value) > 0.5 ? kSbInputEventTypePress
                                  : kSbInputEventTypeUnpress);
  if (previous_type == type) {
    // Key press/unpress state did not change.
    return NULL;
  }

  SbInputData* data = new SbInputData();
  memset(data, 0, sizeof(*data));
  data->window = window;
  data->type = type;
  data->device_type = kSbInputDeviceTypeGamepad;
  data->device_id = kGamepadDeviceId;
  data->key = key;
  data->key_location = location;
  data->key_modifiers = modifiers;
  return new DevInput::Event(kSbEventTypeInput, data,
                             &Application::DeleteDestructor<SbInputData>);
}

// Creates a move event with key for a stick input.
DevInput::Event* CreateMoveEventWithKey(SbWindow window,
                                        SbKey key,
                                        SbKeyLocation location,
                                        int modifiers,
                                        const SbInputVector& input_vector) {
  SbInputData* data = new SbInputData();
  memset(data, 0, sizeof(*data));
  data->window = window;
  data->type = kSbInputEventTypeMove;
  data->device_type = kSbInputDeviceTypeGamepad;
  data->device_id = kGamepadDeviceId;

  data->key = key;
  data->key_location = location;
  data->key_modifiers = modifiers;
  data->position = input_vector;
  data->pressure = NAN;
  data->size = {NAN, NAN};
  data->tilt = {NAN, NAN};

  return new DevInput::Event(kSbEventTypeInput, data,
                             &Application::DeleteDestructor<SbInputData>);
}

DevInput::Event* CreateTouchPadEvent(SbWindow window,
                                     SbInputEventType type,
                                     SbKey key,
                                     SbKeyLocation location,
                                     int modifiers,
                                     const SbInputVector& input_vector) {
  SbInputData* data = new SbInputData();
  memset(data, 0, sizeof(*data));
  data->window = window;
  data->type = type;
  data->device_type = kSbInputDeviceTypeTouchPad;
  data->device_id = kGamepadDeviceId;

  data->key = key;
  data->key_location = location;
  data->key_modifiers = modifiers;
  data->position = input_vector;
  data->pressure = NAN;
  data->size = {NAN, NAN};
  data->tilt = {NAN, NAN};

  return new DevInput::Event(kSbEventTypeInput, data,
                             &Application::DeleteDestructor<SbInputData>);
}

}  // namespace

DevInput::Event* DevInputImpl::AxisInputToApplicationEvent(
    const struct input_event& event,
    int modifiers,
    InputDeviceInfo* device_info) {
  SB_DCHECK(event.type == EV_ABS);
  SbKey key = kSbKeyUnknown;
  float axis_value = 0;
  float previous_axis_value = 0;
  auto axis_info_it = device_info->axis_info.find(event.code);
  if (axis_info_it != device_info->axis_info.end()) {
    struct input_absinfo& axis_info = axis_info_it->second;
    axis_info.value = event.value;
    bool is_trigger = event.code == ABS_Z || event.code == ABS_RZ;
    axis_value = GetAxisValue(is_trigger, device_info->tuning->GetMinimumFlat(),
                              axis_info);
    float& stored_axis_value = device_info->axis_value[event.code];
    previous_axis_value = stored_axis_value;
    if (previous_axis_value == axis_value) {
      // If the value is unchanged, don't do anything.
      return NULL;
    }
    stored_axis_value = axis_value;
  }

  SbKeyLocation location = kSbKeyLocationUnspecified;
  SbInputVector input_vector;
  // The mapping for the axis codes can vary from controller to controller.
  // TODO: Include axis mapping for controllers with different layout.
  // Report up and left as negative values.
  switch (event.code) {
    case ABS_X:
      input_vector.x = axis_value;
      input_vector.y = device_info->axis_value[ABS_Y];
      key = kSbKeyGamepadLeftStickLeft;
      location = kSbKeyLocationLeft;
      return CreateMoveEventWithKey(window_, key, location, modifiers,
                                    input_vector);
    case ABS_Y: {
      input_vector.x = device_info->axis_value[ABS_X];
      input_vector.y = axis_value;
      key = kSbKeyGamepadLeftStickUp;
      location = kSbKeyLocationLeft;
      return CreateMoveEventWithKey(window_, key, location, modifiers,
                                    input_vector);
    }
    case ABS_RX:
      input_vector.x = axis_value;
      input_vector.y = device_info->axis_value[ABS_RZ];
      key = kSbKeyGamepadRightStickLeft;
      location = kSbKeyLocationRight;
      return CreateMoveEventWithKey(window_, key, location, modifiers,
                                    input_vector);
    case ABS_RY:
      input_vector.x = device_info->axis_value[ABS_Z];
      input_vector.y = axis_value;
      key = kSbKeyGamepadRightStickUp;
      location = kSbKeyLocationRight;
      return CreateMoveEventWithKey(window_, key, location, modifiers,
                                    input_vector);
    case ABS_Z: {
      key = kSbKeyGamepadLeftTrigger;
      location = kSbKeyLocationLeft;
      // For trigger buttons, the range is [0..1].
      float trigger_value = (axis_value + 1) / 2;
      float previous_trigger_value = (previous_axis_value + 1) / 2;
      return CreateAnalogButtonKeyEvent(window_, trigger_value,
                                        previous_trigger_value, key, location,
                                        modifiers, event);
    }
    case ABS_RZ: {
      key = kSbKeyGamepadRightTrigger;
      location = kSbKeyLocationRight;
      // For trigger buttons, the range is [0..1].
      float trigger_value = (axis_value + 1) / 2;
      float previous_trigger_value = (previous_axis_value + 1) / 2;
      return CreateAnalogButtonKeyEvent(window_, trigger_value,
                                        previous_trigger_value, key, location,
                                        modifiers, event);
    }
    case ABS_HAT0X: {
      float axis_value_for_key =
          std::abs(axis_value) > 0.5f ? axis_value : previous_axis_value;
      key = (axis_value_for_key < 0) ? kSbKeyGamepadDPadLeft
                                     : kSbKeyGamepadDPadRight;
      return CreateAnalogButtonKeyEvent(window_, axis_value,
                                        previous_axis_value, key, location,
                                        modifiers, event);
    }
    case ABS_HAT0Y: {
      float axis_value_for_key =
          std::abs(axis_value) > 0.5f ? axis_value : previous_axis_value;
      key = (axis_value_for_key < 0) ? kSbKeyGamepadDPadUp
                                     : kSbKeyGamepadDPadDown;
      return CreateAnalogButtonKeyEvent(window_, axis_value,
                                        previous_axis_value, key, location,
                                        modifiers, event);
    }
    case ABS_MT_TRACKING_ID:
      if (event.value == -1) {
        bool touchpad_position_is_known = IsTouchpadPositionKnown(device_info);
        device_info->touchpad_position_state = kTouchPadPositionNone;
        if (touchpad_position_is_known) {
          // Touch point is released, report last known position as unpress.
          input_vector.x = device_info->axis_value[ABS_MT_POSITION_X];
          input_vector.y = device_info->axis_value[ABS_MT_POSITION_Y];
          return CreateTouchPadEvent(window_, kSbInputEventTypeUnpress, key,
                                     location, modifiers, input_vector);
        }
      }
      return NULL;
    case ABS_MT_POSITION_X: {
      // If all positions were known before this event, then this event is a
      // move.
      SbInputEventType type = IsTouchpadPositionKnown(device_info)
                                  ? kSbInputEventTypeMove
                                  : kSbInputEventTypePress;
      device_info->touchpad_position_state |= kTouchPadPositionX;
      if (IsTouchpadPositionKnown(device_info)) {
        // For touchpads, the unit range is [-1..1]. Negative values for top
        // left.
        input_vector.x = axis_value;
        input_vector.y = device_info->axis_value[ABS_MT_POSITION_Y];
        return CreateTouchPadEvent(window_, type, key, location, modifiers,
                                   input_vector);
      }
      // Not all axis positions are known yet.
      return NULL;
    }
    case ABS_MT_POSITION_Y: {
      // If all positions were known before this event, then this event is a
      // move.
      SbInputEventType type = IsTouchpadPositionKnown(device_info)
                                  ? kSbInputEventTypeMove
                                  : kSbInputEventTypePress;
      device_info->touchpad_position_state |= kTouchPadPositionY;
      if (IsTouchpadPositionKnown(device_info)) {
        // For touchpads, the range is [-1..1]. Negative values for top left.
        input_vector.x = device_info->axis_value[ABS_MT_POSITION_X];
        input_vector.y = axis_value;
        return CreateTouchPadEvent(window_, type, key, location, modifiers,
                                   input_vector);
      }
      // Not all axis positions are known yet.
      return NULL;
    }
    default:
      // Ignored event codes.
      return NULL;
  }

  SB_NOTREACHED();
  return NULL;
}

DevInput::Event* DevInputImpl::KeyInputToApplicationEvent(
    const struct input_event& event,
    int modifiers,
    InputDeviceInfo* device_info) {
  SB_DCHECK(event.type == EV_KEY);
  SB_DCHECK(event.value <= 2);

  SbKey key = KeyCodeToSbKey(device_info->tuning
                                 ? device_info->tuning->GetKeyCode(event.code)
                                 : event.code);

  SbInputData* data = new SbInputData();
  memset(data, 0, sizeof(*data));
  data->window = window_;
  data->type =
      (event.value == 0 ? kSbInputEventTypeUnpress : kSbInputEventTypePress);
  data->device_type = kSbInputDeviceTypeKeyboard;
  data->device_id = kKeyboardDeviceId;
  data->key = key;
  data->key_location = KeyCodeToSbKeyLocation(event.code);
  data->key_modifiers = modifiers;
  return new Event(kSbEventTypeInput, data,
                   &Application::DeleteDestructor<SbInputData>);
}

DevInput::Event* DevInputImpl::InputToApplicationEvent(
    const struct input_event& event,
    int modifiers,
    InputDeviceInfo* device_info) {
  // EV_ABS events are axis values: Sticks, dpad, and touchpad.
  // https://www.kernel.org/doc/Documentation/input/event-codes.txt
  switch (event.type) {
    case EV_ABS:
      return AxisInputToApplicationEvent(event, modifiers, device_info);
    case EV_KEY:
      return KeyInputToApplicationEvent(event, modifiers, device_info);
  }
  return NULL;
}

}  // namespace

// static
DevInput* DevInput::Create(SbWindow window) {
  return new DevInputImpl(window);
}

// static
DevInput* DevInput::Create(SbWindow window, int wake_up_fd) {
  return new DevInputImpl(window, wake_up_fd);
}

}  // namespace dev_input
}  // namespace shared
}  // namespace starboard
