// Copyright 2024 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIBTOUCHRAW_PARSER_H_
#define LIBTOUCHRAW_PARSER_H_

#include <memory>
#include <optional>
#include <span>
#include <utility>
#include <vector>

#include <linux/hidraw.h>

#include <base/task/sequenced_task_runner.h>
#include <brillo/udev/udev_device.h>
#include <gtest/gtest_prod.h>

#include "libtouchraw/consumer_interface.h"
#include "libtouchraw/touchraw.h"
#include "libtouchraw/touchraw_export.h"

namespace touchraw {

// Please refer to
// https://www.usb.org/document-library/device-class-definition-hid-111 for HID
// report item format.
struct Item {
  std::span<const uint8_t> data;
  uint8_t data_size;  // Specify size of data. Based on the device class
                      // definition doc section 6.2.2.3, long items may contain
                      // up to 256 bytes of data. So 8 bits is enough here.
  uint16_t size;      // Specify total size of an item.
  uint8_t prefix;     // All items have a one-byte prefix that contains the item
                      // tag, item type, and item size.
};

// Describe a main item of report descriptor.
struct MainItem {
  uint16_t usage_page;
  uint16_t usage;
  uint8_t report_id;
  uint32_t data_size;  // Size of the data field in bytes.
};

// Necessary information to create a main item.
struct MainItemInfo {
  uint16_t usage_page;
  uint16_t usage;
  uint8_t report_id;
  uint32_t report_size;
  uint32_t report_count;
};

class ReportDescriptor {
 public:
  explicit ReportDescriptor(const hidraw_report_descriptor* rpt_desc);

  ReportDescriptor(const ReportDescriptor&) = delete;
  ReportDescriptor& operator=(const ReportDescriptor&) = delete;

  // True if the internal index has not reached the end of the report
  // descriptor; False otherwise.
  bool HasNextItem();
  // Return the next item.
  Item GetNextItem();
  // Reset the internal index.
  void Reset();

 private:
  const hidraw_report_descriptor* rpt_desc_;
  uint16_t next_item_idx_;  // Starting index of the next item to be processed.
};

class LIBTOUCHRAW_EXPORT Parser : public HIDDataConsumerInterface {
 public:
  /**
   * Factory method: creates and returns a Parser.
   * May return null on failure cases that it fails to get a report descriptor
   * or the report descriptor does not support heat map.
   *
   * @param fd File descriptor.
   * @param q HeatmapChunk consumer queue for tasks to be posted.
   * @return Unique pointer of Parser if create succeeds, null pointer
   * otherwise.
   */
  static std::unique_ptr<Parser> Create(
      const int fd, std::unique_ptr<HeatmapChunkConsumerInterface> q);

  static std::unique_ptr<Parser> CreateForTesting(
      std::unique_ptr<HeatmapChunkConsumerInterface> q);

  Parser(const Parser&) = delete;
  Parser& operator=(const Parser&) = delete;

  void Push(std::unique_ptr<const HIDData> data) override {
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, base::BindOnce(&Parser::ParseHIDData, base::Unretained(this),
                                  std::move(data)));
  }

 protected:
  /**
   * Parse HID data read from the file descriptor.
   *
   * @param hid_data
   */
  void ParseHIDData(std::unique_ptr<const HIDData> hid_data);

 private:
  FRIEND_TEST(ParserTest, ValidReportDescriptorWithHeatmap);
  FRIEND_TEST(ParserTest, ValidReportDescriptorWithoutHeatmap);
  FRIEND_TEST(ParserTest, UnknownHidType);

  /**
   * Parser constructor.
   * This class retrieves the input device report descriptor and parses HID data
   * into heatmap chunks.
   *
   * @param q HeatmapChunk consumer queue for tasks to be posted.
   */
  explicit Parser(std::unique_ptr<HeatmapChunkConsumerInterface> q);

  /**
   * Get report descriptor from ioctl.
   *
   * @return Usually, on success zero is returned. On error, -1 is returned, and
   * errno is set to indicate the error.
   */
  int GetReportDescriptorIoctl(const int fd,
                               hidraw_report_descriptor* rpt_desc);

  /**
   * Helper function to create a udev device.
   *
   * @return Unique pointer of UdevDevice if create succeeds, null pointer
   * otherwise.
   */
  std::unique_ptr<brillo::UdevDevice> CreateUdevDevice(const int fd);

  /**
   * Get report descriptor from sysfs.
   *
   * @return Usually, on success zero is returned. On error, -1 is returned, and
   * errno is set to indicate the error.
   */
  int GetReportDescriptorSysfs(const int fd,
                               hidraw_report_descriptor* rpt_desc);
  // TODO: b/317990775 - Extract descriptor parsing into a sub-library of
  // libtouchraw.
  bool ParseHeatmapReportsFromDescriptor(
      const hidraw_report_descriptor* rpt_desc);

  /**
   * Helper function to get data field value.
   *
   * @param index Data field index.
   * @param size Data field size.
   * @return Data field value.
   */
  uint32_t GetDataField(int index, int size, std::span<const uint8_t> payload);

  // Helper function to process items and save report data fields into the
  // usages table.
  void ProcessItem(Item& item);
  // Helper function to get the value of the data field of a report.
  uint32_t GetPropValue(std::span<const uint8_t> data, int data_size);

  // Usages table that contains each usage item from the report descriptor.
  std::vector<MainItem> usages_;
  // Stores the information of each usage item.
  MainItemInfo info_;
  // Offset index of usages table for the first chunk of heat map input report
  // type.
  std::optional<uint16_t> sync_report_offset_;
  // Offset index of usages table for the subsequent chunks of heat map input
  // report type.
  std::optional<uint16_t> sub_report_offset_;

  // Task queue.
  const std::unique_ptr<HeatmapChunkConsumerInterface> q_;
};

}  // namespace touchraw

#endif  // LIBTOUCHRAW_PARSER_H_
