// 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 <hid-parser/parser.h>
#include <hid-parser/usages.h>
#include <hid/paradise.h>

#include <gtest/gtest.h>
#include <lib/fxl/time/time_point.h>

#include "garnet/bin/ui/input_reader/touchscreen.h"

namespace input {

namespace {

void ParseTouchpad(const uint8_t *desc, size_t desc_len,
                   mozart::Touchscreen *ts) {
  hid::DeviceDescriptor *dev_desc = nullptr;
  auto parse_res = hid::ParseReportDescriptor(desc, desc_len, &dev_desc);
  ASSERT_EQ(hid::ParseResult::kParseOk, parse_res);

  auto count = dev_desc->rep_count;
  ASSERT_LT(0UL, count);

  // Find the first input report.
  const hid::ReportDescriptor *input_desc = nullptr;
  for (size_t rep = 0; rep < count; rep++) {
    const hid::ReportDescriptor *desc = &dev_desc->report[rep];
    if (desc->first_field[0].type == hid::kInput) {
      input_desc = desc;
      break;
    }
  }
  ASSERT_NE(nullptr, input_desc);
  ASSERT_LT(0UL, input_desc->count);

  auto success = ts->ParseTouchscreenDescriptor(input_desc);
  ASSERT_EQ(true, success);
}
}  // namespace

// These unit tests exercise any touchpad report descriptors we've collected.
// Each test parses the report descriptor for the touchpad and then sends one
// report to ensure that it has been parsed correctly.
namespace test {

TEST(TouchpadTest, ParadiseV1) {
  mozart::Touchscreen ts;
  size_t desc_size;
  const uint8_t *paradise_touchpad_v1_report_desc =
      get_paradise_touchpad_v1_report_desc(&desc_size);

  ParseTouchpad(paradise_touchpad_v1_report_desc, desc_size, &ts);
  mozart::Touchscreen::Descriptor ts_desc;
  EXPECT_TRUE(ts.SetDescriptor(&ts_desc));

  EXPECT_EQ(5UL, ts.touch_points());
  EXPECT_EQ(mozart::Touchscreen::Capabilities::CONTACT_ID |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::BUTTON |
                mozart::Touchscreen::Capabilities::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(1030000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(680000, ts_desc.y_max);

  // Now use the parsed descriptor to interpret a touchpad report.
  paradise_touchpad_v1_t touchpad_v1_report = {};
  touchpad_v1_report.report_id = 12;
  touchpad_v1_report.fingers[1].tip_switch = 0x1;
  touchpad_v1_report.fingers[1].id = 0x1;
  touchpad_v1_report.fingers[1].x = 100;
  touchpad_v1_report.fingers[1].y = 200;

  touchpad_v1_report.fingers[2].tip_switch = 0x1;
  touchpad_v1_report.fingers[2].id = 0x2;
  touchpad_v1_report.fingers[2].x = 300;
  touchpad_v1_report.fingers[2].y = 400;

  uint8_t *report_data = reinterpret_cast<uint8_t *>(&touchpad_v1_report);

  mozart::Touchscreen::Report report;
  auto success =
      ts.ParseReport(report_data, sizeof(touchpad_v1_report), &report);
  EXPECT_EQ(true, success);

  EXPECT_EQ(2UL, report.contact_count);

  // The X and Y values below have been manually calculated based on the above
  // input and the logical/physical conversion given by the report descriptor.
  EXPECT_EQ(1U, report.contacts[0].id);
  EXPECT_EQ(7812, report.contacts[0].x);
  EXPECT_EQ(15625, report.contacts[0].y);

  EXPECT_EQ(2U, report.contacts[1].id);
  EXPECT_EQ(23437, report.contacts[1].x);
  EXPECT_EQ(31250, report.contacts[1].y);
}

TEST(TouchpadTest, ParadiseV2) {
  mozart::Touchscreen ts;
  size_t desc_size;
  const uint8_t *paradise_touchpad_v2_report_desc =
      get_paradise_touchpad_v2_report_desc(&desc_size);

  ParseTouchpad(paradise_touchpad_v2_report_desc, desc_size, &ts);
  mozart::Touchscreen::Descriptor ts_desc;
  EXPECT_TRUE(ts.SetDescriptor(&ts_desc));

  EXPECT_EQ(5UL, ts.touch_points());
  EXPECT_EQ(mozart::Touchscreen::Capabilities::CONTACT_ID |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::BUTTON |
                mozart::Touchscreen::Capabilities::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(1030000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(680000, ts_desc.y_max);

  // Now use the parsed descriptor to interpret a touchpad report.
  paradise_touchpad_v2_t touchpad_v2_report = {};
  touchpad_v2_report.report_id = 12;
  touchpad_v2_report.fingers[1].tip_switch = 0x1;
  touchpad_v2_report.fingers[1].id = 0x1;
  touchpad_v2_report.fingers[1].x = 100;
  touchpad_v2_report.fingers[1].y = 200;

  touchpad_v2_report.fingers[2].tip_switch = 0x1;
  touchpad_v2_report.fingers[2].id = 0x2;
  touchpad_v2_report.fingers[2].x = 300;
  touchpad_v2_report.fingers[2].y = 400;

  uint8_t *report_data = reinterpret_cast<uint8_t *>(&touchpad_v2_report);

  mozart::Touchscreen::Report report;
  auto success =
      ts.ParseReport(report_data, sizeof(touchpad_v2_report), &report);
  EXPECT_EQ(true, success);

  EXPECT_EQ(2UL, report.contact_count);

  // The X and Y values below have been manually calculated based on the above
  // input and the logical/physical conversion given by the report descriptor.
  EXPECT_EQ(1U, report.contacts[0].id);
  EXPECT_EQ(7812, report.contacts[0].x);
  EXPECT_EQ(15625, report.contacts[0].y);

  EXPECT_EQ(2U, report.contacts[1].id);
  EXPECT_EQ(23437, report.contacts[1].x);
  EXPECT_EQ(31250, report.contacts[1].y);
}

}  // namespace test
}  // namespace input
