// 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/tests/touchscreen_test_data.h"
#include "garnet/bin/ui/input_reader/touchscreen.h"

namespace input {

namespace {

void ParseTouchscreen(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 the touchscreen examples in touchscreen_test_data.h
// Each test parses the report descriptor for the touchscreen and then sends one
// report to ensure that it has been parsed correctly.
namespace test {

TEST(TouchscreenTest, Gechic1101) {
  mozart::Touchscreen ts;
  ParseTouchscreen(gechic1101_hid_descriptor, sizeof(gechic1101_hid_descriptor),
                   &ts);
  mozart::Touchscreen::Descriptor ts_desc;
  EXPECT_TRUE(ts.SetDescriptor(&ts_desc));

  EXPECT_EQ(10UL, ts.touch_points());
  EXPECT_EQ(mozart::Touchscreen::Capabilities::CONTACT_ID |
                mozart::Touchscreen::Capabilities::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::SCAN_TIME,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(2563000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(1442000, ts_desc.y_max);

  uint8_t report_data[] = {
      0x04,                                            // Report ID
      0x40, 0x22, 0x21, 0x1f, 0x17,                    // Finger 0
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 1
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 2
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 3
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 4
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 5
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 6
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 7
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 8
      0x00, 0x00, 0x00, 0x00, 0x00,                    // Finger 9
      0x00, 0x0a, 0x00, 0x00,                          // Scan Time
      0x01,                                            // Contact Time
      0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // Constant Value
  };

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

  EXPECT_EQ(1UL, report.contact_count);
  EXPECT_EQ(0xa00u, report.scan_time);

  EXPECT_EQ(0U, report.contacts[0].id);
  // Test that X and Y have been converted to micrometers
  // These values have been manually calculated based on the above report_data
  EXPECT_EQ(1326865, report.contacts[0].x);
  EXPECT_EQ(889083, report.contacts[0].y);
}

TEST(TouchscreenTest, CoolTouch) {
  mozart::Touchscreen ts;
  ParseTouchscreen(cooltouch_10x_hid_descriptor,
                   sizeof(cooltouch_10x_hid_descriptor), &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::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::SCAN_TIME,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(2771000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(1561000, ts_desc.y_max);

  uint8_t report_data[] = {
      0x01,                          // Report ID
      0x09, 0x6f, 0x3b, 0x1e, 0x4b,  // Finger 0
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 1
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 2
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 3
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 4
      0x4c, 0x00,                    // Scan Time
      0x01,                          // Contact Count
  };

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

  EXPECT_EQ(1UL, report.contact_count);
  EXPECT_EQ(0x004cU, report.scan_time);

  EXPECT_EQ(1U, report.contacts[0].id);
  // Test that X and Y have been converted to micrometers
  // These values have been manually calculated based on the above report_data
  EXPECT_EQ(1286683, report.contacts[0].x);
  EXPECT_EQ(916105, report.contacts[0].y);
}

TEST(TouchscreenTest, WaveShare) {
  mozart::Touchscreen ts;
  ParseTouchscreen(waveshare_hid_descriptor, sizeof(waveshare_hid_descriptor),
                   &ts);

  mozart::Touchscreen::Descriptor ts_desc;
  EXPECT_TRUE(ts.SetDescriptor(&ts_desc));

  EXPECT_EQ(1UL, ts.touch_points());
  EXPECT_EQ(mozart::Touchscreen::Capabilities::CONTACT_ID |
                mozart::Touchscreen::Capabilities::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::SCAN_TIME,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(655350000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(655350000, ts_desc.y_max);

  uint8_t report_data[] = {
      0x01,        // Report ID
      0x01,        // Tip Switch
      0x00,        // Contact ID
      0x03,        // Tip Pressure
      0xa0, 0x02,  // X
      0x46, 0x01,  // Y
      0xf4, 0xd4,  // Scan Time
      0x01,        // Contact Count
  };

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

  EXPECT_EQ(1UL, report.contact_count);
  EXPECT_EQ(0xd4f4U, report.scan_time);

  EXPECT_EQ(0U, report.contacts[0].id);
  // Test that X and Y have been converted to micrometers
  // These values have been manually calculated based on the above report_data
  EXPECT_EQ(430073437, report.contacts[0].x);
  EXPECT_EQ(356073500, report.contacts[0].y);
}

TEST(TouchscreenTest, Gechic1303) {
  mozart::Touchscreen ts;
  ParseTouchscreen(gechic_1303_hid_descriptor,
                   sizeof(gechic_1303_hid_descriptor), &ts);

  mozart::Touchscreen::Descriptor ts_desc;
  EXPECT_TRUE(ts.SetDescriptor(&ts_desc));

  EXPECT_EQ(10UL, ts.touch_points());
  EXPECT_EQ(mozart::Touchscreen::Capabilities::CONTACT_ID |
                mozart::Touchscreen::Capabilities::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::SCAN_TIME,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(5090000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(2860000, ts_desc.y_max);

  uint8_t report_data[] = {
      0x04,                          // Report ID
      0x40, 0xef, 0x1e, 0xe9, 0x15,  // Finger 0
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 1
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 2
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 3
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 4
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 5
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 6
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 7
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 8
      0x00, 0x00, 0x00, 0x00, 0x00,  // Finger 9
      0xc0, 0x2b, 0x00, 0x00,        // Scan Time
      0x01,                          // Contact Count
  };

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

  EXPECT_EQ(1UL, report.contact_count);
  EXPECT_EQ(0x2bc0U, report.scan_time);

  EXPECT_EQ(0U, report.contacts[0].id);

  // Test that X and Y have been converted to micrometers
  // These values have been manually calculated based on the above report_data
  EXPECT_EQ(2460187, report.contacts[0].x);
  EXPECT_EQ(1671014, report.contacts[0].y);
}

TEST(TouchscreenTest, ParadiseV1) {
  mozart::Touchscreen ts;
  size_t desc_size;
  const uint8_t *paradise_touch_v1_report_desc =
      get_paradise_touch_report_desc(&desc_size);

  ParseTouchscreen(paradise_touch_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::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::SCAN_TIME,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(2592000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(1728000, ts_desc.y_max);

  // Now use the parsed descriptor to interpret a touchpad report.
  paradise_touch_t touch_v1_report = {};
  touch_v1_report.rpt_id = 12;
  touch_v1_report.contact_count = 1;
  touch_v1_report.scan_time = 0xabc;
  touch_v1_report.fingers[1].flags = 0xF;
  touch_v1_report.fingers[1].finger_id = 0x1;
  touch_v1_report.fingers[1].x = 100;
  touch_v1_report.fingers[1].y = 200;

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

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

  EXPECT_EQ(1UL, report.contact_count);
  EXPECT_EQ(72U, report.scan_time);

  EXPECT_EQ(1U, report.contacts[0].id);
  EXPECT_EQ(25000, report.contacts[0].x);
  EXPECT_EQ(50000, report.contacts[0].y);
}

TEST(TouchscreenTest, ParadiseV2) {
  mozart::Touchscreen ts;
  size_t desc_size;
  const uint8_t *paradise_touch_v2_report_desc =
      get_paradise_touch_v2_report_desc(&desc_size);

  ParseTouchscreen(paradise_touch_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::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::SCAN_TIME,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(2592000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(1728000, ts_desc.y_max);

  // Now use the parsed descriptor to interpret a touchpad report.
  paradise_touch_v2_t touch_v2_report = {};
  touch_v2_report.rpt_id = 12;
  touch_v2_report.contact_count = 1;
  touch_v2_report.scan_time = 0xabc;
  touch_v2_report.fingers[1].flags = 0xF;
  touch_v2_report.fingers[1].finger_id = 0x1;
  touch_v2_report.fingers[1].x = 100;
  touch_v2_report.fingers[1].y = 200;

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

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

  EXPECT_EQ(1UL, report.contact_count);
  EXPECT_EQ(0xabcU, report.scan_time);

  EXPECT_EQ(1U, report.contacts[0].id);
  EXPECT_EQ(25000, report.contacts[0].x);
  EXPECT_EQ(50000, report.contacts[0].y);
}

TEST(TouchscreenTest, ParadiseV3) {
  mozart::Touchscreen ts;
  size_t desc_size;
  const uint8_t *paradise_touch_v3_report_desc =
      get_paradise_touch_v3_report_desc(&desc_size);

  ParseTouchscreen(paradise_touch_v3_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::TIP_SWITCH |
                mozart::Touchscreen::Capabilities::X |
                mozart::Touchscreen::Capabilities::Y |
                mozart::Touchscreen::Capabilities::CONTACT_COUNT |
                mozart::Touchscreen::Capabilities::SCAN_TIME,
            ts.capabilities());
  EXPECT_EQ(0, ts_desc.x_min);
  EXPECT_EQ(2593000, ts_desc.x_max);
  EXPECT_EQ(0, ts_desc.y_min);
  EXPECT_EQ(1729000, ts_desc.y_max);

  // Now use the parsed descriptor to interpret a touchpad report.
  // The v3 report is the same as the v1 report.
  paradise_touch_t touch_v3_report = {};
  touch_v3_report.rpt_id = 12;
  touch_v3_report.contact_count = 1;
  touch_v3_report.scan_time = 0xabc;
  touch_v3_report.fingers[1].flags = 0xF;
  touch_v3_report.fingers[1].finger_id = 0x1;
  touch_v3_report.fingers[1].x = 100;
  touch_v3_report.fingers[1].y = 200;

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

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

  EXPECT_EQ(1UL, report.contact_count);
  EXPECT_EQ(72U, report.scan_time);

  EXPECT_EQ(1U, report.contacts[0].id);
  EXPECT_EQ(25000, report.contacts[0].x);
  EXPECT_EQ(50000, report.contacts[0].y);
}

}  // namespace test
}  // namespace input
