// 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 "garnet/bin/ui/input_reader/mouse.h"
#include "garnet/bin/ui/input_reader/device.h"

#include <hid-parser/parser.h>
#include <hid-parser/report.h>
#include <hid-parser/units.h>
#include <hid-parser/usages.h>

#include <stdint.h>
#include <stdio.h>
#include <vector>

#include <lib/fxl/logging.h>

namespace mozart {

bool Mouse::ParseReportDescriptor(
    const hid::ReportDescriptor& report_descriptor,
    Descriptor* device_descriptor) {
  hid::Attributes left_click = {};
  hid::Attributes middle_click = {};
  hid::Attributes right_click = {};
  hid::Attributes x = {};
  hid::Attributes y = {};
  uint32_t caps = 0;

  for (size_t i = 0; i < report_descriptor.input_count; i++) {
    const hid::ReportField& field = report_descriptor.input_fields[i];

    if (field.attr.usage == hid::USAGE(hid::usage::Page::kButton, 1)) {
      left_click = field.attr;
      caps |= Capabilities::LEFT_CLICK;

    } else if (field.attr.usage == hid::USAGE(hid::usage::Page::kButton, 2)) {
      middle_click = field.attr;
      caps |= Capabilities::MIDDLE_CLICK;

    } else if (field.attr.usage == hid::USAGE(hid::usage::Page::kButton, 3)) {
      right_click = field.attr;
      caps |= Capabilities::RIGHT_CLICK;

    } else if (field.attr.usage == hid::USAGE(hid::usage::Page::kGenericDesktop,
                                              hid::usage::GenericDesktop::kX)) {
      x = field.attr;
      caps |= Capabilities::X;

    } else if (field.attr.usage == hid::USAGE(hid::usage::Page::kGenericDesktop,
                                              hid::usage::GenericDesktop::kY)) {
      y = field.attr;
      caps |= Capabilities::Y;
    }
  }

  uint32_t base_caps =
      (Capabilities::X | Capabilities::Y | Capabilities::LEFT_CLICK);
  if ((caps & base_caps) != base_caps) {
    FXL_LOG(ERROR) << "Mouse descriptor: Missing basic capabilities";
    return false;
  }

  // No error, write to class members.
  left_click_ = left_click;
  middle_click_ = middle_click;
  right_click_ = right_click;
  x_ = x;
  y_ = y;
  capabilities_ = caps;

  report_size_ = report_descriptor.input_byte_sz;
  report_id_ = report_descriptor.report_id;

  // Set the device descriptor.
  device_descriptor->protocol = Protocol::Mouse;
  device_descriptor->has_mouse = true;
  device_descriptor->mouse_type = MouseDeviceType::HID;
  device_descriptor->mouse_descriptor =
      fuchsia::ui::input::MouseDescriptor::New();
  // At the moment all mice send relative units, so these min and max values
  // do not affect anything. Set them to maximum range.
  device_descriptor->mouse_descriptor->rel_x.range.min = INT32_MIN;
  device_descriptor->mouse_descriptor->rel_x.range.max = INT32_MAX;
  device_descriptor->mouse_descriptor->rel_x.resolution = 1;

  device_descriptor->mouse_descriptor->rel_y.range.min = INT32_MIN;
  device_descriptor->mouse_descriptor->rel_y.range.max = INT32_MAX;
  device_descriptor->mouse_descriptor->rel_y.resolution = 1;

  device_descriptor->mouse_descriptor->buttons |=
      fuchsia::ui::input::kMouseButtonPrimary;
  device_descriptor->mouse_descriptor->buttons |=
      fuchsia::ui::input::kMouseButtonSecondary;
  device_descriptor->mouse_descriptor->buttons |=
      fuchsia::ui::input::kMouseButtonTertiary;

  return true;
}

bool Mouse::ParseReport(const uint8_t* data, size_t len,
                        fuchsia::ui::input::InputReport* report) {
  FXL_CHECK(report);
  FXL_CHECK(report->mouse);

  if (data[0] != report_id_) {
    FXL_VLOG(0) << " Mouse report " << static_cast<uint32_t>(data[0])
                << " does not match report id "
                << static_cast<uint32_t>(report_id_);
  }

  Report mouse_report = {};
  if (len != report_size_) {
    FXL_LOG(ERROR) << "Mouse HID Report is not correct size, (" << len
                   << " != " << report_size_ << ")";
    return false;
  }

  uint32_t clicked;
  if (capabilities_ & Capabilities::LEFT_CLICK) {
    if (!hid::ExtractUint(data, len, left_click_, &clicked)) {
      FXL_LOG(ERROR) << "Mouse report: Failed to parse LEFT_CLICK";
      return false;
    }
    mouse_report.left_click = (clicked == 1);
  }
  if (capabilities_ & Capabilities::MIDDLE_CLICK) {
    if (!hid::ExtractUint(data, len, middle_click_, &clicked)) {
      FXL_LOG(ERROR) << "Mouse report: Failed to parse MIDDLE_CLICK";
      return false;
    }
    mouse_report.middle_click = (clicked == 1);
  }
  if (capabilities_ & Capabilities::RIGHT_CLICK) {
    if (!hid::ExtractUint(data, len, right_click_, &clicked)) {
      FXL_LOG(ERROR) << "Mouse report: Failed to parse RIGHT_CLICK";
      return false;
    }
    mouse_report.right_click = (clicked == 1);
  }

  // rel_x and rel_y will have units of 10^-5 meters if the report defines units
  hid::Unit length_unit = {};
  length_unit.exp = -5;
  hid::unit::SetSystem(length_unit, hid::unit::System::si_linear);
  hid::unit::SetLengthExp(length_unit, 1);

  if (capabilities_ & Capabilities::X) {
    double x;
    if (!hid::ExtractAsUnit(data, len, x_, &x)) {
      FXL_LOG(ERROR) << "Mouse report: Failed to parse X";
      return false;
    }

    // If this returns true, scan_time was converted. If it returns false,
    // scan_time is unchanged. Either way we return successfully.
    hid::unit::ConvertUnits(x_.unit, x, length_unit, &x);

    mouse_report.rel_x = static_cast<int32_t>(x);
  }
  if (capabilities_ & Capabilities::Y) {
    double y;
    if (!hid::ExtractAsUnit(data, len, y_, &y)) {
      FXL_LOG(ERROR) << "Mouse report: Failed to parse Y";
      return false;
    }

    // If this returns true, scan_time was converted. If it returns false,
    // scan_time is unchanged. Either way we return successfully.
    hid::unit::ConvertUnits(y_.unit, y, length_unit, &y);

    mouse_report.rel_y = static_cast<int32_t>(y);
  }

  // Now that we can't fail, set the real report.
  report->mouse->rel_x = mouse_report.rel_x;
  report->mouse->rel_y = mouse_report.rel_y;

  report->mouse->pressed_buttons = 0;
  report->mouse->pressed_buttons |=
      mouse_report.left_click ? fuchsia::ui::input::kMouseButtonPrimary : 0;
  report->mouse->pressed_buttons |=
      mouse_report.middle_click ? fuchsia::ui::input::kMouseButtonSecondary : 0;
  report->mouse->pressed_buttons |=
      mouse_report.right_click ? fuchsia::ui::input::kMouseButtonTertiary : 0;

  return true;
}

}  // namespace mozart
