// Copyright 2019 The Fuchsia 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 "src/ui/lib/input_reader/keyboard.h"

#include <fuchsia/ui/input/cpp/fidl.h>

#include <gtest/gtest.h>
#include <hid-parser/parser.h>
#include <hid-parser/usages.h>
#include <hid/boot.h>
#include <hid/usages.h>

#include "src/lib/fxl/time/time_point.h"

namespace input {

namespace test {

namespace {

// This is a keyboard with multiple keys of the same usage.
const uint8_t double_keys_keyboard[] = {
    0x05, 0x01,  // Usage Page (Generic Desktop Ctrls)
    0x09, 0x06,  // Usage (Keyboard)
    0xA1, 0x01,  // Collection (Application)
    0x05, 0x07,  //   Usage Page (Kbrd/Keypad)
    0x19, 0xE0,  //   Usage Minimum (0xE0)
    0x29, 0xE7,  //   Usage Maximum (0xE7)
    0x15, 0x00,  //   Logical Minimum (0)
    0x25, 0x01,  //   Logical Maximum (1)
    0x75, 0x01,  //   Report Size (1)
    0x95, 0x08,  //   Report Count (8)
    0x81, 0x02,  //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x19, 0xE0,  //   Usage Minimum (0xE0)
    0x29, 0xE7,  //   Usage Maximum (0xE7)
    0x15, 0x00,  //   Logical Minimum (0)
    0x25, 0x01,  //   Logical Maximum (1)
    0x75, 0x01,  //   Report Size (1)
    0x95, 0x08,  //   Report Count (8)
    0x81, 0x02,  //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0x95, 0x02,  //   Report Count (2)
    0x75, 0x08,  //   Report Size (8)
    0x15, 0x00,  //   Logical Minimum (0)
    0x25, 0x65,  //   Logical Maximum (101)
    0x05, 0x07,  //   Usage Page (Kbrd/Keypad)
    0x19, 0x00,  //   Usage Minimum (0x00)
    0x29, 0x65,  //   Usage Maximum (0x65)
    0x81, 0x00,  //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
    0xC0,        // End Collection
};

}  // namespace

// This test double checks that we don't double count keys that are included twice.
TEST(KeyboardTest, DoubleCountingKeys) {
  hid::DeviceDescriptor* dev_desc = nullptr;
  auto parse_res =
      hid::ParseReportDescriptor(double_keys_keyboard, sizeof(double_keys_keyboard), &dev_desc);
  ASSERT_EQ(hid::ParseResult::kParseOk, parse_res);

  // Test the descriptor parses correctly.
  ui_input::Keyboard keyboard = {};
  ui_input::Device::Descriptor device_descriptor = {};
  bool success = keyboard.ParseReportDescriptor(dev_desc->report[0], &device_descriptor);
  ASSERT_TRUE(success);
  ASSERT_TRUE(device_descriptor.has_keyboard);

  EXPECT_EQ(device_descriptor.keyboard_descriptor->keys.size(), 109U);

  // Test that all of the expected keys are here.
  for (size_t i = 0; i < 101; i++) {
    EXPECT_EQ(device_descriptor.keyboard_descriptor->keys[i], i);
  }

  for (size_t i = 101; i < 109; i++) {
    EXPECT_EQ(device_descriptor.keyboard_descriptor->keys[i], 0xE0 + (i - 101));
  }
}

TEST(KeyboardTest, BootKeyboard) {
  size_t descriptor_size;
  const uint8_t* boot_keyboard_descriptor = get_boot_kbd_report_desc(&descriptor_size);

  hid::DeviceDescriptor* dev_desc = nullptr;
  auto parse_res = hid::ParseReportDescriptor(boot_keyboard_descriptor, descriptor_size, &dev_desc);
  ASSERT_EQ(hid::ParseResult::kParseOk, parse_res);

  // Test the descriptor parses correctly.
  ui_input::Keyboard keyboard = {};
  ui_input::Device::Descriptor device_descriptor = {};
  bool success = keyboard.ParseReportDescriptor(dev_desc->report[0], &device_descriptor);
  ASSERT_TRUE(success);
  ASSERT_TRUE(device_descriptor.has_keyboard);
  EXPECT_EQ(device_descriptor.keyboard_descriptor->keys.size(), 109U);

  // Test a report parses correctly.
  hid_boot_kbd_report kbd_report = {};
  kbd_report.modifier = HID_KBD_MODIFIER_LEFT_SHIFT | HID_KBD_MODIFIER_RIGHT_GUI;
  kbd_report.usage[0] = HID_USAGE_KEY_A;
  kbd_report.usage[1] = HID_USAGE_KEY_NON_US_BACKSLASH;
  kbd_report.usage[2] = HID_USAGE_KEY_UP;

  fuchsia::ui::input::InputReport report;
  report.keyboard = fuchsia::ui::input::KeyboardReport::New();
  success =
      keyboard.ParseReport(reinterpret_cast<uint8_t*>(&kbd_report), sizeof(kbd_report), &report);
  ASSERT_EQ(true, success);

  ASSERT_EQ(report.keyboard->pressed_keys.size(), 5U);
  EXPECT_EQ(report.keyboard->pressed_keys[0], HID_USAGE_KEY_LEFT_SHIFT);
  EXPECT_EQ(report.keyboard->pressed_keys[1], HID_USAGE_KEY_RIGHT_GUI);
  EXPECT_EQ(report.keyboard->pressed_keys[2], HID_USAGE_KEY_A);
  EXPECT_EQ(report.keyboard->pressed_keys[3], HID_USAGE_KEY_NON_US_BACKSLASH);
  EXPECT_EQ(report.keyboard->pressed_keys[4], HID_USAGE_KEY_UP);
}

}  // namespace test
}  // namespace input
