// 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/pointer.h"

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

#include <vector>

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

#include "src/lib/fxl/logging.h"

namespace ui_input {

bool Pointer::ParseReportDescriptor(const hid::ReportDescriptor& report_descriptor,
                                    Descriptor* device_descriptor) {
  hid::Attributes button = {};
  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)) {
      button = field.attr;
      caps |= Capabilities::BUTTON;

    } 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::BUTTON);
  if ((caps & base_caps) != base_caps) {
    FXL_LOG(INFO) << "Pointer descriptor: Missing basic capabilities";
    return false;
  }

  // No error, write to class members.
  button_ = button;
  x_ = x;
  y_ = y;
  capabilities_ = caps;

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

  device_descriptor->protocol = Protocol::Touch;
  device_descriptor->has_touchscreen = true;
  device_descriptor->touch_type = TouchDeviceType::HID;

  device_descriptor->touchscreen_descriptor = fuchsia::ui::input::TouchscreenDescriptor::New();
  device_descriptor->touchscreen_descriptor->x.range.min = x.phys_mm.min;
  device_descriptor->touchscreen_descriptor->x.range.max = x.phys_mm.max;
  device_descriptor->touchscreen_descriptor->x.resolution = 1;

  device_descriptor->touchscreen_descriptor->y.range.min = y.phys_mm.min;
  device_descriptor->touchscreen_descriptor->y.range.max = y.phys_mm.max;
  device_descriptor->touchscreen_descriptor->y.resolution = 1;

  device_descriptor->touchscreen_descriptor->max_finger_id = 1;

  return true;
}

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

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

  uint32_t button;
  if (capabilities_ & Capabilities::BUTTON) {
    if (!hid::ExtractUint(data, len, button_, &button)) {
      FXL_LOG(INFO) << "Pointer report: Failed to parse BUTTON";
      return false;
    }
    // Return early if the screen is not being pressed.
    if (!button) {
      report->touchscreen->touches.resize(0);
      return true;
    }
  }

  fuchsia::ui::input::Touch touch = {};
  touch.finger_id = 0;
  touch.width = 5;
  touch.height = 5;

  if (capabilities_ & Capabilities::X) {
    uint32_t x = 0;
    if (!hid::ExtractUint(data, len, x_, &x)) {
      FXL_LOG(INFO) << "Pointer report: Failed to parse X";
      return false;
    }
    touch.x = x;
  }

  if (capabilities_ & Capabilities::Y) {
    uint32_t y = 0;
    if (!hid::ExtractUint(data, len, y_, &y)) {
      FXL_LOG(INFO) << "Pointer report: Failed to parse Y";
      return false;
    }
    touch.y = y;
  }

  report->touchscreen->touches.resize(1);
  report->touchscreen->touches.at(0) = std::move(touch);

  return true;
}

}  // namespace ui_input
