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

#include <linux/input.h>
#include <string.h>

#include "starboard/common/log.h"
#include "starboard/input.h"
#include "starboard/key.h"
#include "starboard/memory.h"
#include "starboard/shared/starboard/application.h"
#include "starboard/shared/wayland/application_wayland.h"

namespace starboard {
namespace shared {
namespace wayland {

namespace {

// YouTube Technical Requirement 2018 (2016/11/1 - Initial draft)
// 9.5 The device MUST dispatch the following key events, as appropriate:
//  * Window.keydown
//      * After a key is held down for 500ms, the Window.keydown event
//        MUST repeat every 50ms until a user stops holding the key down.
//  * Window.keyup
const SbTime kKeyHoldTime = 500 * kSbTimeMillisecond;
const SbTime kKeyRepeatTime = 50 * kSbTimeMillisecond;

void SeatHandleCapabilities(void* data,
                            struct wl_seat* seat,
                            unsigned int caps) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnSeatCapabilitiesChanged(seat, caps);
}

const struct wl_seat_listener seat_listener = {
    &SeatHandleCapabilities,
};

#define KEY_INFO_BUTTON 0xbc

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

    case KEY_INFO_BUTTON:
      return kSbKeyF1;
  }
  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;
}

void KeyboardHandleKeyMap(void* data,
                          struct wl_keyboard* keyboard,
                          uint32_t format,
                          int fd,
                          uint32_t size) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleKeyMap(keyboard, format, fd, size);
}

void KeyboardHandleEnter(void* data,
                         struct wl_keyboard* keyboard,
                         uint32_t serial,
                         struct wl_surface* surface,
                         struct wl_array* keys) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleEnter(keyboard, serial, surface, keys);
}

void KeyboardHandleLeave(void* data,
                         struct wl_keyboard* keyboard,
                         uint32_t serial,
                         struct wl_surface* surface) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleLeave(keyboard, serial, surface);
}

void KeyboardHandleKey(void* data,
                       struct wl_keyboard* keyboard,
                       uint32_t serial,
                       uint32_t time,
                       uint32_t key,
                       uint32_t state) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleKey(keyboard, serial, time, key, state);
}

void KeyboardHandleModifiers(void* data,
                             struct wl_keyboard* keyboard,
                             uint32_t serial,
                             uint32_t mods_depressed,
                             uint32_t mods_latched,
                             uint32_t mods_locked,
                             uint32_t group) {
  DevInput* dev_input = reinterpret_cast<DevInput*>(data);
  SB_DCHECK(dev_input);
  dev_input->OnKeyboardHandleModifiers(keyboard, serial, mods_depressed,
                                       mods_latched, mods_locked, group);
}

const struct wl_keyboard_listener keyboard_listener = {
    &KeyboardHandleKeyMap, &KeyboardHandleEnter,     &KeyboardHandleLeave,
    &KeyboardHandleKey,    &KeyboardHandleModifiers,
};

}  // namespace

DevInput::DevInput()
    : wl_seat_(NULL),
      wl_keyboard_(NULL),
      key_repeat_event_id_(kSbEventIdInvalid),
      key_repeat_interval_(kKeyHoldTime),
      key_modifiers_(0),
      window_(kSbWindowInvalid) {}

bool DevInput::OnGlobalObjectAvailable(struct wl_registry* registry,
                                       uint32_t name,
                                       const char* interface,
                                       uint32_t version) {
  if (strcmp(interface, "wl_seat") == 0) {
    wl_seat_ = static_cast<wl_seat*>(
        wl_registry_bind(registry, name, &wl_seat_interface, 1));
    SB_DCHECK(wl_seat_);
    wl_seat_add_listener(wl_seat_, &seat_listener, this);
    return true;
  }
  return false;
}

void DevInput::OnSeatCapabilitiesChanged(struct wl_seat* seat,
                                         unsigned int caps) {
  SB_DLOG(INFO) << "[Key] seat_handle_capabilities caps: " << caps;
  if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
    wl_keyboard_ = static_cast<wl_keyboard*>(wl_seat_get_keyboard(seat));
    if (wl_keyboard_)
      wl_keyboard_add_listener(wl_keyboard_, &keyboard_listener, this);
  } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
    if (wl_keyboard_)
      wl_keyboard_destroy(wl_keyboard_);
    wl_keyboard_ = NULL;
  }
}

void DevInput::OnKeyboardHandleKeyMap(struct wl_keyboard* keyboard,
                                      uint32_t format,
                                      int fd,
                                      uint32_t size) {
  SB_DLOG(INFO) << "[Key] Keyboard keymap";
}

void DevInput::OnKeyboardHandleEnter(struct wl_keyboard* keyboard,
                                     uint32_t serial,
                                     struct wl_surface* surface,
                                     struct wl_array* keys) {
  SB_DLOG(INFO) << "[Key] Keyboard gained focus";
}

void DevInput::OnKeyboardHandleLeave(struct wl_keyboard* keyboard,
                                     uint32_t serial,
                                     struct wl_surface* surface) {
  SB_DLOG(INFO) << "[Key] Keyboard lost focus";
  DeleteRepeatKey();
}

void DevInput::OnKeyboardHandleModifiers(struct wl_keyboard* keyboard,
                                         uint32_t serial,
                                         uint32_t mods_depressed,
                                         uint32_t mods_latched,
                                         uint32_t mods_locked,
                                         uint32_t group) {
  // Convert to SbKeyModifiers.
  unsigned int modifiers = kSbKeyModifiersNone;

  if (mods_depressed & 1)
    modifiers |= kSbKeyModifiersShift;
  if (mods_depressed & 4)
    modifiers |= kSbKeyModifiersCtrl;
  if (mods_depressed & 8)
    modifiers |= kSbKeyModifiersAlt;

  SB_DLOG(INFO) << "[Key] Modifiers depressed " << mods_depressed
                << ", latched " << mods_latched << ", locked " << mods_locked
                << ", group " << group << ", key modifiers " << modifiers;

  key_modifiers_ = modifiers;
}

void DevInput::OnKeyboardHandleKey(struct wl_keyboard* keyboard,
                                   uint32_t serial,
                                   uint32_t time,
                                   uint32_t key,
                                   uint32_t state) {
  bool repeatable =
      (key == KEY_LEFT || key == KEY_RIGHT || key == KEY_UP || key == KEY_DOWN);
  SB_DLOG(INFO) << "[Key] Key :" << key << ", state:" << state << " repeatable "
                << repeatable << " key_repeat_key_ " << key_repeat_key_
                << " key_repeat_state_ " << key_repeat_state_;
  if (state && repeatable && key == key_repeat_key_ && key_repeat_state_)
    return;

  if (repeatable) {
    CreateKey(key, state, true);
  } else {
    CreateKey(key, state, false);
  }
}

void DevInput::CreateRepeatKey() {
  if (!key_repeat_state_) {
    return;
  }

  if (key_repeat_interval_) {
    key_repeat_interval_ = kKeyRepeatTime;
  }

  CreateKey(key_repeat_key_, key_repeat_state_, true);
}

void DevInput::CreateKey(int key, int state, bool is_repeat) {
  SbInputData* data = new SbInputData();
  SbMemorySet(data, 0, sizeof(*data));
  data->timestamp = SbTimeGetMonotonicNow();
  data->window = window_;
  data->type = (state == 0 ? kSbInputEventTypeUnpress : kSbInputEventTypePress);
  data->device_type = kSbInputDeviceTypeRemote;
  data->device_id = 1;  // kKeyboardDeviceId;
  data->key = KeyCodeToSbKey(key);
  data->key_location = KeyCodeToSbKeyLocation(key);
  data->key_modifiers = key_modifiers_;
  ApplicationWayland::Get()->InjectInputEvent(data);

  DeleteRepeatKey();

  if (is_repeat && state) {
    key_repeat_key_ = key;
    key_repeat_state_ = state;
    key_repeat_event_id_ = SbEventSchedule(
        [](void* data) {
          DevInput* dev_input = reinterpret_cast<DevInput*>(data);
          dev_input->CreateRepeatKey();
        },
        this, key_repeat_interval_);
  } else {
    key_repeat_interval_ = kKeyHoldTime;
  }
}

void DevInput::DeleteRepeatKey() {
  key_repeat_state_ = 0;
  if (key_repeat_event_id_ != kSbEventIdInvalid) {
    SbEventCancel(key_repeat_event_id_);
    key_repeat_event_id_ = kSbEventIdInvalid;
  }
}

}  // namespace wayland
}  // namespace shared
}  // namespace starboard
