// 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 <fuchsia/input/report/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl-async/cpp/bind.h>
#include <lib/sync/completion.h>

#include <string>
#include <vector>

#include <ddk/device.h>
#include <fbl/auto_lock.h>
#include <fbl/mutex.h>
#include <gtest/gtest.h>
#include <hid/usages.h>

#include "src/ui/input/testing/fake_input_report_device/fake.h"
#include "src/ui/tools/print-input-report/devices.h"
#include "src/ui/tools/print-input-report/printer.h"

namespace test {

namespace fuchsia_input_report = ::llcpp::fuchsia::input::report;

class FakePrinter : public print_input_report::Printer {
 public:
  void RealPrint(const char* format, va_list argptr) override {
    char buf[kMaxBufLen];
    vsprintf(buf, format, argptr);

    ASSERT_LT(current_string_index_, expected_strings_.size());
    const std::string& expected = expected_strings_[current_string_index_];
    current_string_index_++;

    // Check that we match the expected string.
    ASSERT_GT(expected.size(), indent_);
    int cmp = strcmp(buf, expected.c_str());
    if (cmp != 0) {
      printf("Wanted string: '%s'\n", expected.c_str());
      printf("Saw string:    '%s'\n", buf);
      ASSERT_TRUE(false);
    }

    // Print the string for easy debugging.
    vprintf(format, argptr);

    va_end(argptr);
  }

  void SetExpectedStrings(const std::vector<std::string>& strings) {
    current_string_index_ = 0;
    expected_strings_ = strings;
  }

 private:
  static constexpr size_t kMaxBufLen = 1024;
  size_t current_string_index_ = 0;
  std::vector<std::string> expected_strings_;
};

class PrintInputReport : public testing::Test {
 protected:
  virtual void SetUp() {
    // Make the channels and the fake device.
    zx::channel token_server, token_client;
    ASSERT_EQ(zx::channel::create(0, &token_server, &token_client), ZX_OK);

    loop_ = std::make_unique<async::Loop>(&kAsyncLoopConfigNoAttachToCurrentThread);

    fake_device_ = std::make_unique<fake_input_report_device::FakeInputDevice>(
        fidl::InterfaceRequest<fuchsia::input::report::InputDevice>(std::move(token_server)),
        loop_->dispatcher());
    ASSERT_EQ(ZX_OK, loop_->StartThread("print-input-report-test-thread"));
    client_ = fuchsia_input_report::InputDevice::SyncClient(std::move(token_client));
  }

  virtual void TearDown() {
    loop_->Quit();
    loop_->JoinThreads();
  }

  std::unique_ptr<fake_input_report_device::FakeInputDevice> fake_device_;
  std::unique_ptr<async::Loop> loop_;
  std::optional<fuchsia_input_report::InputDevice::SyncClient> client_;
};

TEST_F(PrintInputReport, PrintMouseInputReport) {
  fuchsia::input::report::InputReport report;
  report.mutable_mouse()->set_movement_x(100);
  report.mutable_mouse()->set_movement_y(200);
  report.mutable_mouse()->set_position_x(300);
  report.mutable_mouse()->set_position_y(400);
  report.mutable_mouse()->set_scroll_v(100);
  report.mutable_mouse()->set_pressed_buttons({1, 10, 5});

  std::vector<fuchsia::input::report::InputReport> reports;
  reports.push_back(std::move(report));
  fake_device_->SetReports(std::move(reports));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Movement x: 00000100\n",
      "Movement y: 00000200\n",
      "Position x: 00000300\n",
      "Position y: 00000400\n",
      "Scroll v: 00000100\n",
      "Button 01 pressed\n",
      "Button 10 pressed\n",
      "Button 05 pressed\n",
      "\n",
  });
  print_input_report::PrintInputReport(&printer, &client_.value(), 1);
}

TEST_F(PrintInputReport, PrintMouseInputDescriptor) {
  auto descriptor = std::make_unique<fuchsia::input::report::DeviceDescriptor>();
  auto mouse = descriptor->mutable_mouse()->mutable_input();

  fuchsia::input::report::Axis axis;
  axis.unit.type = fuchsia::input::report::UnitType::METERS;
  axis.unit.exponent = 0;
  axis.range.min = -100;
  axis.range.max = -100;
  mouse->set_movement_x(axis);

  axis.unit.type = fuchsia::input::report::UnitType::NONE;
  axis.range.min = -200;
  axis.range.max = -200;
  mouse->set_movement_y(axis);

  axis.range.min = 300;
  axis.range.max = 300;
  mouse->set_position_x(axis);

  axis.range.min = 400;
  axis.range.max = 400;
  mouse->set_position_y(axis);

  mouse->set_buttons({1, 10, 5});

  fake_device_->SetDescriptor(std::move(descriptor));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Mouse Descriptor:\n",  "  Movement X:\n", "    Unit:   METERS\n", "    Min:      -100\n",
      "    Max:      -100\n", "  Movement Y:\n", "    Unit:     NONE\n", "    Min:      -200\n",
      "    Max:      -200\n", "  Position X:\n", "    Unit:     NONE\n", "    Min:       300\n",
      "    Max:       300\n", "  Position Y:\n", "    Unit:     NONE\n", "    Min:       400\n",
      "    Max:       400\n", "  Button: 1\n",   "  Button: 10\n",       "  Button: 5\n",
  });

  print_input_report::PrintInputDescriptor(&printer, &client_.value());
}

TEST_F(PrintInputReport, PrintSensorInputDescriptor) {
  auto descriptor = std::make_unique<fuchsia::input::report::DeviceDescriptor>();
  auto values = descriptor->mutable_sensor()->mutable_input()->mutable_values();

  fuchsia::input::report::SensorAxis axis;
  axis.axis.unit.type = fuchsia::input::report::UnitType::SI_LINEAR_VELOCITY;
  axis.axis.unit.exponent = 0;
  axis.axis.range.min = 0;
  axis.axis.range.max = 1000;
  axis.type = fuchsia::input::report::SensorType::ACCELEROMETER_X;

  values->push_back(axis);

  axis.axis.unit.type = fuchsia::input::report::UnitType::LUX;
  axis.type = fuchsia::input::report::SensorType::LIGHT_ILLUMINANCE;

  values->push_back(axis);

  fake_device_->SetDescriptor(std::move(descriptor));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Sensor Descriptor:\n",
      "  Value 00:\n",
      "    SensorType: ACCELEROMETER_X\n",
      "    Unit: SI_LINEAR_VELOCITY\n",
      "    Min:         0\n",
      "    Max:      1000\n",
      "  Value 01:\n",
      "    SensorType: LIGHT_ILLUMINANCE\n",
      "    Unit:      LUX\n",
      "    Min:         0\n",
      "    Max:      1000\n",
  });

  print_input_report::PrintInputDescriptor(&printer, &client_.value());
}

TEST_F(PrintInputReport, PrintSensorInputReport) {
  fuchsia::input::report::InputReport report;
  report.mutable_sensor()->set_values({100, -100});

  std::vector<fuchsia::input::report::InputReport> reports;
  reports.push_back(std::move(report));
  fake_device_->SetReports(std::move(reports));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Sensor[00]: 00000100\n",
      "Sensor[01]: -0000100\n",
      "\n",
  });

  print_input_report::PrintInputReport(&printer, &client_.value(), 1);
}

TEST_F(PrintInputReport, PrintTouchInputDescriptor) {
  auto descriptor = std::make_unique<fuchsia::input::report::DeviceDescriptor>();
  auto touch = descriptor->mutable_touch()->mutable_input();
  touch->set_touch_type(fuchsia::input::report::TouchType::TOUCHSCREEN);
  touch->set_max_contacts(100);

  fuchsia::input::report::Axis axis;
  axis.unit.type = fuchsia::input::report::UnitType::NONE;
  axis.unit.exponent = 0;
  axis.range.min = 0;
  axis.range.max = 300;

  fuchsia::input::report::ContactInputDescriptor contact;
  contact.set_position_x(axis);

  axis.range.max = 500;
  contact.set_position_y(axis);

  axis.range.max = 100;
  contact.set_pressure(axis);

  touch->mutable_contacts()->push_back(std::move(contact));

  fake_device_->SetDescriptor(std::move(descriptor));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Touch Descriptor:\n",
      "  Touch Type: TOUCHSCREEN\n",
      "  Max Contacts: 100\n",
      "  Contact: 00\n",
      "    Position X:\n",
      "      Unit:     NONE\n",
      "      Min:         0\n",
      "      Max:       300\n",
      "    Position Y:\n",
      "      Unit:     NONE\n",
      "      Min:         0\n",
      "      Max:       500\n",
      "    Pressure:\n",
      "      Unit:     NONE\n",
      "      Min:         0\n",
      "      Max:       100\n",
  });

  print_input_report::PrintInputDescriptor(&printer, &client_.value());
}

TEST_F(PrintInputReport, PrintTouchInputReport) {
  fuchsia::input::report::InputReport report;
  fuchsia::input::report::ContactInputReport contact;

  contact.set_contact_id(10);
  contact.set_position_x(123);
  contact.set_position_y(234);
  contact.set_pressure(345);
  contact.set_contact_width(678);
  contact.set_contact_height(789);

  report.mutable_touch()->mutable_contacts()->push_back(std::move(contact));

  std::vector<fuchsia::input::report::InputReport> reports;
  reports.push_back(std::move(report));
  fake_device_->SetReports(std::move(reports));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Contact ID: 10\n",
      "  Position X:     00000123\n",
      "  Position Y:     00000234\n",
      "  Pressure:       00000345\n",
      "  Contact Width:  00000678\n",
      "  Contact Height: 00000789\n",
      "\n",
  });

  print_input_report::PrintInputReport(&printer, &client_.value(), 1);
}

TEST_F(PrintInputReport, PrintKeyboardDescriptor) {
  auto descriptor = std::make_unique<fuchsia::input::report::DeviceDescriptor>();
  descriptor->mutable_keyboard()->mutable_input()->set_keys({fuchsia::ui::input2::Key::A,
                                                             fuchsia::ui::input2::Key::UP,
                                                             fuchsia::ui::input2::Key::LEFT_SHIFT});
  descriptor->mutable_keyboard()->mutable_output()->set_leds(
      {fuchsia::input::report::LedType::CAPS_LOCK, fuchsia::input::report::LedType::SCROLL_LOCK});

  fake_device_->SetDescriptor(std::move(descriptor));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Keyboard Descriptor:\n",
      "Input Report:\n",
      "  Key:        1\n",
      "  Key:       79\n",
      "  Key:       82\n",
      "Output Report:\n",
      "  Led: CAPS_LOCK\n",
      "  Led: SCROLL_LOCK\n",
  });

  print_input_report::PrintInputDescriptor(&printer, &client_.value());
}

TEST_F(PrintInputReport, PrintKeyboardInputReport) {
  fuchsia::input::report::InputReport report;
  report.mutable_keyboard()->set_pressed_keys({fuchsia::ui::input2::Key::A,
                                               fuchsia::ui::input2::Key::UP,
                                               fuchsia::ui::input2::Key::LEFT_SHIFT});

  std::vector<fuchsia::input::report::InputReport> reports;
  reports.push_back(std::move(report));
  fake_device_->SetReports(std::move(reports));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Keyboard Report\n",
      "  Key:        1\n",
      "  Key:       79\n",
      "  Key:       82\n",
      "\n",
  });

  print_input_report::PrintInputReport(&printer, &client_.value(), 1);
}

TEST_F(PrintInputReport, PrintKeyboardInputReportNoKeys) {
  fuchsia::input::report::InputReport report;
  report.mutable_keyboard()->set_pressed_keys({});

  std::vector<fuchsia::input::report::InputReport> reports;
  reports.push_back(std::move(report));
  fake_device_->SetReports(std::move(reports));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "Keyboard Report\n",
      "  No keys pressed\n",
      "\n",
  });

  print_input_report::PrintInputReport(&printer, &client_.value(), 1);
}

TEST_F(PrintInputReport, PrintConsumerControlDescriptor) {
  auto descriptor = std::make_unique<fuchsia::input::report::DeviceDescriptor>();
  descriptor->mutable_consumer_control()->mutable_input()->set_buttons(
      {fuchsia::input::report::ConsumerControlButton::VOLUME_UP,
       fuchsia::input::report::ConsumerControlButton::VOLUME_DOWN,
       fuchsia::input::report::ConsumerControlButton::REBOOT});

  fake_device_->SetDescriptor(std::move(descriptor));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "ConsumerControl Descriptor:\n",
      "Input Report:\n",
      "  Button:        VOLUME_UP\n",
      "  Button:      VOLUME_DOWN\n",
      "  Button:           REBOOT\n",
      "\n",
  });

  print_input_report::PrintInputDescriptor(&printer, &client_.value());
}

TEST_F(PrintInputReport, PrintConsumerControlReport) {
  fuchsia::input::report::InputReport report;
  report.mutable_consumer_control()->set_pressed_buttons(
      {fuchsia::input::report::ConsumerControlButton::VOLUME_UP,
       fuchsia::input::report::ConsumerControlButton::VOLUME_DOWN,
       fuchsia::input::report::ConsumerControlButton::REBOOT});

  std::vector<fuchsia::input::report::InputReport> reports;
  reports.push_back(std::move(report));
  fake_device_->SetReports(std::move(reports));

  FakePrinter printer;
  printer.SetExpectedStrings(std::vector<std::string>{
      "ConsumerControl Report\n",
      "  Button:        VOLUME_UP\n",
      "  Button:      VOLUME_DOWN\n",
      "  Button:           REBOOT\n",
      "\n",
  });

  print_input_report::PrintInputReport(&printer, &client_.value(), 1);
}

}  // namespace test
