// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "minios/key_reader.h"

#include <ctype.h>
#include <dirent.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sys/epoll.h>
#include <unistd.h>

#include <algorithm>
#include <utility>
#include <vector>

#include <base/files/file_enumerator.h>
#include <base/logging.h>
#include <base/strings/strcat.h>
#include <base/values.h>

namespace minios {

// Key state parameter.
const int kFdsMax = 10;

namespace {
constexpr char kDevInputEvent[] = "/dev/input";
constexpr char kEventDevName[] = "*event*";
constexpr char kXkbPathName[] = "/usr/share/X11/xkb";

// Offset between xkb layout codes and ev key codes.
constexpr int kXkbOffset = 8;

// Determines if the given |bit| is set in the |bitmask| array.
bool TestBit(const int bit, const uint8_t* bitmask) {
  return (bitmask[bit / 8] >> (bit % 8)) & 1;
}

bool IsUsbDevice(const int fd) {
  struct input_id id;
  if (ioctl(fd, EVIOCGID, &id) == -1) {
    PLOG(ERROR) << "Failed to ioctl to determine device bus";
    return false;
  }

  return id.bustype == BUS_USB;
}

bool IsKeyboardDevice(const int fd) {
  uint8_t evtype_bitmask[EV_MAX / 8 + 1];
  if (ioctl(fd, EVIOCGBIT(0, sizeof(evtype_bitmask)), evtype_bitmask) == -1) {
    PLOG(ERROR) << "Failed to ioctl to determine supported event types";
    return false;
  }

  // The device is a "keyboard" if it supports EV_KEY events. Though, it is not
  // necessarily a real keyboard; EV_KEY events could also be e.g. volume
  // up/down buttons on a device.
  return TestBit(EV_KEY, evtype_bitmask);
}

}  // namespace

KeyReader::KeyReader(bool include_usb)
    : include_usb_(include_usb),
      use_only_evwaitkey_(true),
      delegate_(nullptr) {}

KeyReader::KeyReader(bool include_usb, std::string keyboard_layout)
    : repeated_key_(0),
      repeated_counter_(0),
      return_pressed_(false),
      include_usb_(include_usb),
      keyboard_layout_(keyboard_layout),
      use_only_evwaitkey_(false) {
  user_input_.reserve(kMaxInputLength);
}

KeyReader::~KeyReader() {
  // Release xkb references.
  if (ctx_ != nullptr) {
    xkb_state_unref(state_);
    xkb_keymap_unref(keymap_);
    xkb_context_unref(ctx_);
  }
}

bool KeyReader::Init(const std::vector<int>& valid_keys) {
  keys_ = valid_keys;

  if (!GetValidFds(/*check_supported_keys=*/true)) {
    LOG(ERROR) << "No valid input devices found.";
    return false;
  }
  if (!EpollCreate(&epfd_)) {
    PLOG(ERROR) << " EpollCreate failed, cannot watch epfd.";
    return false;
  }

  // Set the file descriptor watcher.
  return StartWatcher();
}

bool KeyReader::SupportsAllKeys(const int fd) {
  uint8_t key_bitmask[KEY_MAX / 8 + 1];
  if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) == -1) {
    PLOG(ERROR) << "Failed to ioctl to determine supported key events";
    return false;
  }

  for (const auto& key : keys_) {
    if (!TestBit(key, key_bitmask))
      return false;
  }
  return true;
}

bool KeyReader::GetValidFds(bool check_supported_keys) {
  fds_.clear();
  base::FileEnumerator file_enumerator(base::FilePath(kDevInputEvent), true,
                                       base::FileEnumerator::FILES,
                                       FILE_PATH_LITERAL(kEventDevName));

  for (base::FilePath dir_path = file_enumerator.Next(); !dir_path.empty();
       dir_path = file_enumerator.Next()) {
    base::ScopedFD fd(open(dir_path.value().c_str(), O_RDONLY | O_CLOEXEC));
    if (!fd.is_valid()) {
      continue;
    }

    if ((include_usb_ || !IsUsbDevice(fd.get())) &&
        IsKeyboardDevice(fd.get())) {
      if (!check_supported_keys || SupportsAllKeys(fd.get())) {
        fds_.push_back(std::move(fd));
      }
    }
  }
  return !fds_.empty();
}

bool KeyReader::EpollCreate(base::ScopedFD* epfd) {
  *epfd = base::ScopedFD(epoll_create1(EPOLL_CLOEXEC));
  if (epfd->get() < 0) {
    PLOG(ERROR) << "Epoll_create failed";
    return false;
  }

  for (int i = 0; i < fds_.size(); ++i) {
    struct epoll_event ep_event {
      .events = EPOLLIN, .data.u32 = static_cast<uint32_t>(i),
    };
    if (epoll_ctl(epfd->get(), EPOLL_CTL_ADD, fds_[i].get(), &ep_event) < 0) {
      PLOG(ERROR) << "Epoll_ctl failed";
      return false;
    }
  }
  return true;
}

bool KeyReader::GetEpEvent(int epfd, struct input_event* ev) {
  struct epoll_event ep_event;
  if (epoll_wait(epfd, &ep_event, 1, -1) <= 0) {
    PLOG(ERROR) << "epoll_wait failed";
    return false;
  }
  if (HANDLE_EINTR(read(fds_[ep_event.data.u32].get(), ev, sizeof(*ev))) !=
      sizeof(*ev)) {
    PLOG(ERROR) << "Could not read event";
    return false;
  }
  return true;
}

void KeyReader::OnKeyEvent() {
  struct input_event ev;
  if (!GetEpEvent(epfd_.get(), &ev)) {
    PLOG(ERROR) << "Could not get event";
    return;
  }

  if (!delegate_) {
    return;
  }

  if (ev.type != EV_KEY || ev.code > KEY_MAX) {
    return;
  }

  if (std::find(keys_.begin(), keys_.end(), ev.code) == keys_.end()) {
    return;
  }

  switch (ev.value) {
    case kKeyPress:
      delegate_->OnKeyPress(ev.code);
      repeated_counter_ = 0;
      return;
    case kKeyHold:
      if (repeated_key_ != ev.code) {
        repeated_key_ = ev.code;
        repeated_counter_ = 0;
        return;
      }
      if (++repeated_counter_ < kRepeatedSensitivity) {
        return;
      }
      repeated_counter_ = 0;
      delegate_->OnKeyPress(ev.code);
      return;
    default:
      return;
  }
}

bool KeyReader::SetKeyboardContext() {
  // Set xkb layout and get keymap.
  ctx_ = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES);
  if (!ctx_) {
    LOG(ERROR) << "Unable to get new xkb context.";
    return false;
  }
  if (!xkb_context_include_path_append(ctx_, kXkbPathName)) {
    LOG(ERROR) << "Cannot add path " << kXkbPathName << " to context.";
    return false;
  }
  names_ = {.layout = keyboard_layout_.c_str()};
  keymap_ =
      xkb_keymap_new_from_names(ctx_, &names_, XKB_KEYMAP_COMPILE_NO_FLAGS);
  if (keymap_ == nullptr) {
    LOG(ERROR) << "No matching keyboard for " << keyboard_layout_
               << ". Make sure the two letter country code is valid.";
    return false;
  }
  state_ = xkb_state_new(keymap_);
  if (!state_) {
    LOG(ERROR) << "Unable to get xkbstate for " << keyboard_layout_;
    return false;
  }
  return true;
}

bool KeyReader::InputSetUp() {
  if (use_only_evwaitkey_) {
    LOG(ERROR) << "Please construct the class with include_usb and "
                  "country_code in order to correctly use this function.";
    return false;
  }

  if (!GetValidFds(/*check_supported_keys=*/false)) {
    LOG(ERROR) << "No valid input devices found.";
    return false;
  }

  if (!EpollCreate(&epfd_)) {
    return false;
  }

  if (!SetKeyboardContext()) {
    return false;
  }
  user_input_.clear();
  return true;
}

bool KeyReader::GetChar(const struct input_event& ev, bool* tab_toggle) {
  const xkb_keycode_t key_code = ev.code + kXkbOffset;

  if (ev.value == kKeyRelease) {
    // Update underlying state on release.
    xkb_state_update_key(state_, key_code, XKB_KEY_UP);
  } else if (ev.value == kKeyPress) {
    xkb_state_update_key(state_, key_code, XKB_KEY_DOWN);
    const xkb_keysym_t sym = xkb_state_key_get_one_sym(state_, key_code);
    // Only return false when `return` key is pressed.
    if (sym == XKB_KEY_Return)
      return false;
    if (sym == XKB_KEY_Tab) {
      *tab_toggle = !(*tab_toggle);
      return true;
    }
    // Put char representation in buffer.
    int size = xkb_state_key_get_utf8(state_, key_code, nullptr, 0) + 1;
    std::vector<char> buff(size);
    xkb_state_key_get_utf8(state_, key_code, buff.data(), size);

    if (sym == XKB_KEY_BackSpace && !user_input_.empty()) {
      user_input_.pop_back();
    } else if (isprint(buff[0]) && user_input_.size() < kMaxInputLength) {
      // Only printable ASCII characters stored in output.
      user_input_.push_back(buff[0]);
    }
  } else if (ev.value == kKeyHold) {
    // Long press or repeating key event. Only backspace is supported in this
    // case, ignore all other keys.
    const xkb_keysym_t sym = xkb_state_key_get_one_sym(state_, key_code);
    if (repeated_key_ != ev.code) {
      repeated_key_ = ev.code;
      repeated_counter_ = 0;
    }
    if (sym == XKB_KEY_BackSpace && !user_input_.empty() &&
        ++repeated_counter_ >= kRepeatedSensitivity) {
      // Remove characters until empty.
      user_input_.pop_back();
      repeated_counter_ = 0;
    }
  }
  return true;
}

bool KeyReader::GetUserInput(bool* enter,
                             bool* tab_toggle,
                             std::string* user_input) {
  struct input_event ev;
  if (!GetEpEvent(epfd_.get(), &ev)) {
    PLOG(ERROR) << "Could not get event";
    return false;
  }

  if (ev.type != EV_KEY || ev.code > KEY_MAX) {
    return true;
  }
  // Take in ev event and add to user input as appropriate.
  // Returns false to indicate enter was pressed.
  if (!GetChar(ev, tab_toggle)) {
    *enter = true;
  }
  *user_input = user_input_;
  return true;
}

bool KeyReader::StartWatcher() {
  watcher_ = base::FileDescriptorWatcher::WatchReadable(
      epfd_.get(),
      base::BindRepeating(&KeyReader::OnKeyEvent, base::Unretained(this)));
  if (!watcher_) {
    LOG(ERROR) << "Failed to watch epoll fd.";
    return false;
  }
  return true;
}

void KeyReader::StopWatcher() {
  watcher_ = nullptr;
}

bool KeyReader::GetCharForTest(const struct input_event& ev) {
  bool tab_key = false;
  return GetChar(ev, &tab_key);
}

std::string KeyReader::GetUserInputForTest() {
  return user_input_;
}

}  // namespace minios
