// 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.

#include "libtouchraw/parser.h"

#include <linux/hidraw.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>

#include <limits>
#include <memory>
#include <span>
#include <string>
#include <utility>
#include <vector>

#include <base/containers/span.h>
#include <base/files/file.h>
#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <brillo/udev/udev.h>
#include <brillo/udev/udev_device.h>

namespace touchraw {

constexpr int kByte = 0x08;           // Number of bits per byte.
constexpr int kShortItemSize = 0x04;  // Maximum data size for short items.

constexpr int kHidDigitizersPage = 0x0d;
constexpr int kHidDGHeatMapProtocolVendorID = 0x6a;
constexpr int kHidDGHeatMapProtocolVersion = 0x6b;
constexpr int kHidDGScanTime = 0x56;
constexpr int kHidDGHeatMapFrameData = 0x6c;

constexpr int kHidGenericDesktopPage = 0x01;
constexpr int kHidGDByteCount = 0x3b;

constexpr int kHidGenericDeviceControlsPage = 0x06;
constexpr int kHidGDCSequenceID = 0x27;

constexpr int kHIDLongItemPrefix = 0xfe;
constexpr int kHIDItemPrefixMask = 0xfc;
constexpr int kHIDGlobalItemTagUsagePage = 0x04;
constexpr int kHIDLocalItemTagUsage = 0x08;
constexpr int kHIDMainItemTagInput = 0x80;
constexpr int kHIDGlobalItemTagReportID = 0x84;
constexpr int kHIDGlobalItemTagReportSize = 0x74;
constexpr int kHIDGlobalItemTagReportCount = 0x94;

ReportDescriptor::ReportDescriptor(const hidraw_report_descriptor* rpt_desc)
    : rpt_desc_(rpt_desc), next_item_idx_(0) {}

bool ReportDescriptor::HasNextItem() {
  return next_item_idx_ < rpt_desc_->size;
}

Item ReportDescriptor::GetNextItem() {
  Item item;
  int cur_item_idx = next_item_idx_;
  int data_offset;  // Data starting index of an item.

  // Process item prefix.
  if (cur_item_idx < rpt_desc_->size) {
    item.prefix = rpt_desc_->value[cur_item_idx];
    if (rpt_desc_->value[cur_item_idx] == kHIDLongItemPrefix) {  // Long item.
      data_offset = 3;
      item.data_size = rpt_desc_->value[cur_item_idx + 1];
    } else {  // Short item.
      data_offset = 1;
      item.data_size =
          ((item.prefix & 0x03) == 0x03) ? 4 : (item.prefix & 0x03);
    }
    item.size = item.data_size + data_offset;
    next_item_idx_ += item.size;  // Update the index to next item.
  }

  // Copy item data.
  if (next_item_idx_ <= rpt_desc_->size) {
    item.data =
        std::span<const uint8_t>(rpt_desc_->value + cur_item_idx + data_offset,
                                 rpt_desc_->value + next_item_idx_);
  }

  return item;
}

void ReportDescriptor::Reset() {
  next_item_idx_ = 0;
}

std::unique_ptr<Parser> Parser::Create(
    const int fd, std::unique_ptr<HeatmapChunkConsumerInterface> q) {
  // Using `new` to access a non-public constructor.
  std::unique_ptr<Parser> parser = base::WrapUnique(new Parser(std::move(q)));
  hidraw_report_descriptor rpt_desc;

  if (parser->GetReportDescriptorSysfs(fd, &rpt_desc) != 0) {
    if (parser->GetReportDescriptorIoctl(fd, &rpt_desc) != 0) {
      return nullptr;
    }
  }
  if (!parser->ParseHeatmapReportsFromDescriptor(&rpt_desc)) {
    LOG(WARNING) << "The report descriptor does not support heatmap";
    return nullptr;
  }
  return parser;
}

std::unique_ptr<Parser> Parser::CreateForTesting(
    std::unique_ptr<HeatmapChunkConsumerInterface> q) {
  return base::WrapUnique(new Parser(std::move(q)));
}

Parser::Parser(std::unique_ptr<HeatmapChunkConsumerInterface> q)
    : q_(std::move(q)) {}

int Parser::GetReportDescriptorIoctl(const int fd,
                                     hidraw_report_descriptor* rpt_desc) {
  int res, desc_size = 0;

  LOG(INFO) << "Get report descriptor from hidraw.";

  // Get Report Descriptor Size.
  res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size);
  if (res < 0) {
    LOG(WARNING) << "Failed to get report descriptor size: " << strerror(errno);
    return res;
  }

  // Get Report Descriptor.
  rpt_desc->size = desc_size;
  res = ioctl(fd, HIDIOCGRDESC, rpt_desc);
  if (res < 0) {
    LOG(WARNING) << "Failed to get report descriptor: " << strerror(errno);
  }
  return res;
}

std::unique_ptr<brillo::UdevDevice> Parser::CreateUdevDevice(const int fd) {
  base::stat_wrapper_t stat_buf;
  dev_t devnum;

  // Get the dev_t (major/minor numbers) from the file handle.
  if (base::File::Fstat(fd, &stat_buf) == -1) {
    LOG(WARNING) << "Failed to stat device handle " << fd << ": "
                 << strerror(errno);
    return nullptr;
  }
  devnum = stat_buf.st_rdev;

  // Create a udev device.
  std::unique_ptr<brillo::Udev> udev = brillo::Udev::Create();
  auto dev = udev->CreateDeviceFromDeviceNumber('c', devnum);
  if (!dev) {
    LOG(WARNING) << "Could not get udev entry for device with MAJOR: "
                 << major(devnum) << " MINOR: " << minor(devnum);
    return nullptr;
  }
  return dev;
}

int Parser::GetReportDescriptorSysfs(const int fd,
                                     hidraw_report_descriptor* rpt_desc) {
  int res;
  std::string rpt_path;

  auto dev = CreateUdevDevice(fd);
  if (!dev) {
    LOG(WARNING) << "Failed to create a udev device";
    return -1;
  }

  // Construct <sysfs_path>/device/report_descriptor.
  rpt_path = std::string(dev->GetSysPath()) + "/device/report_descriptor";
  base::File file(base::FilePath(rpt_path),
                  base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!file.IsValid()) {
    LOG(WARNING) << "Could not open " << rpt_path;
    return -1;
  }

  memset(rpt_desc, 0x0, sizeof(*rpt_desc));
  auto read_result = file.Read(0, base::span(rpt_desc->value));
  res = read_result.has_value() ? static_cast<int>(*read_result) : -1;
  if (res < 0) {
    LOG(WARNING) << "Error reading " << rpt_path;
  }
  rpt_desc->size = static_cast<uint32_t>(res);

  return res;
}

uint32_t Parser::GetPropValue(std::span<const uint8_t> data, int data_size) {
  // Does not support long items for now.
  if (data_size > kShortItemSize) {
    LOG(WARNING) << "Not supported - data size is " << data_size;
    return std::numeric_limits<uint32_t>::max();
  }

  uint32_t value = 0;
  for (int i = 0; i < data_size; ++i) {
    value |= data[i] << (i * kByte);
  }

  return value;
}

void Parser::ProcessItem(Item& item) {
  switch (item.prefix & kHIDItemPrefixMask) {
    case kHIDGlobalItemTagUsagePage:
      info_.usage_page = GetPropValue(item.data, item.data_size);
      break;
    case kHIDLocalItemTagUsage:
      info_.usage = GetPropValue(item.data, item.data_size);
      break;
    case kHIDMainItemTagInput:
      if (info_.usage_page == kHidDigitizersPage &&
          info_.usage == kHidDGHeatMapProtocolVendorID) {
        if (!sync_report_offset_.has_value()) {
          sync_report_offset_ = usages_.size();
        } else {
          sub_report_offset_ = usages_.size();
        }
      }
      usages_.push_back({info_.usage_page, info_.usage, info_.report_id,
                         static_cast<uint16_t>(info_.report_size *
                                               info_.report_count / kByte)});
      break;
    case kHIDGlobalItemTagReportID:
      info_.report_id = item.data[0];
      break;
    case kHIDGlobalItemTagReportSize:
      info_.report_size = GetPropValue(item.data, item.data_size);
      break;
    case kHIDGlobalItemTagReportCount:
      info_.report_count = GetPropValue(item.data, item.data_size);
      break;
    default:
      break;
  }
}

bool Parser::ParseHeatmapReportsFromDescriptor(
    const hidraw_report_descriptor* rpt_desc) {
  ReportDescriptor descriptor(rpt_desc);
  LOG(INFO) << "Parse report descriptor.";

  // Parse report descriptor.
  // TODO: b/320780085 - Validate report descriptor collection that represents
  // the heatmap data.
  while (descriptor.HasNextItem()) {
    Item item = descriptor.GetNextItem();
    ProcessItem(item);
  }
  return sync_report_offset_.has_value();
}

void Parser::ParseHIDData(std::unique_ptr<const HIDData> hid_data) {
  int cur = 0;
  uint16_t offset = 0;
  auto chunk = std::make_unique<HeatmapChunk>();

  // Discards HIDData for unsupported report_ids.
  if (sync_report_offset_ &&
      hid_data->report_id == usages_[sync_report_offset_.value()].report_id) {
    offset = sync_report_offset_.value();
  } else if (sub_report_offset_ &&
             hid_data->report_id ==
                 usages_[sub_report_offset_.value()].report_id) {
    offset = sub_report_offset_.value();
  } else {
    DLOG(INFO) << "Report id " << static_cast<int>(hid_data->report_id)
               << ": Not heat map data.";
    return;
  }

  chunk->report_type = ReportType::kInvalid;

  for (int i = offset; usages_[i].report_id == hid_data->report_id; ++i) {
    switch (usages_[i].usage_page) {
      case kHidDigitizersPage:
        switch (usages_[i].usage) {
          case kHidDGHeatMapProtocolVendorID:
            chunk->vendor_id =
                GetDataField(cur, usages_[i].data_size, hid_data->payload);
            break;
          case kHidDGHeatMapProtocolVersion:
            chunk->protocol_version =
                GetDataField(cur, usages_[i].data_size, hid_data->payload);
            break;
          case kHidDGScanTime:
            chunk->scan_time =
                GetDataField(cur, usages_[i].data_size, hid_data->payload);
            break;
          case kHidDGHeatMapFrameData:
            // TODO: b/320780085 - Validate report descriptor collection that
            // represents the heatmap data
            chunk->payload.assign(hid_data->payload.begin() + cur,
                                  hid_data->payload.end());
            if (chunk->payload.size() != usages_[i].data_size) {
              LOG(WARNING) << "Discard this chunk because chunk size "
                           << chunk->payload.size()
                           << " is not equal to the expected size "
                           << usages_[i].data_size;
              return;
            }
            break;
          default:
            break;
        }
        break;
      case kHidGenericDesktopPage:
        switch (usages_[i].usage) {
          case kHidGDByteCount:
            chunk->byte_count =
                GetDataField(cur, usages_[i].data_size, hid_data->payload);
            chunk->report_type = ReportType::kFirst;
            break;
          default:
            break;
        }
        break;
      case kHidGenericDeviceControlsPage:
        switch (usages_[i].usage) {
          case kHidGDCSequenceID:
            chunk->sequence_id =
                GetDataField(cur, usages_[i].data_size, hid_data->payload);
            chunk->report_type = ReportType::kSubsequent;
            break;
          default:
            break;
        }
        break;
      default:
        break;
    }
    cur += usages_[i].data_size;
  }

  // Dispatch.
  q_->Push(std::move(chunk));
}

// Support short items only - data size is limited to 4 bytes.
uint32_t Parser::GetDataField(int index,
                              int size,
                              std::span<const uint8_t> payload) {
  if ((index + size) >= payload.size()) {
    LOG(WARNING) << "Data out of range.";
    return std::numeric_limits<uint32_t>::max();
  }
  // Does not support long items for now.
  if (size > kShortItemSize) {
    LOG(WARNING) << "Not supported - data size is " << size;
    return std::numeric_limits<uint32_t>::max();
  }

  uint32_t value = 0;
  for (int i = 0; i < size; ++i) {
    value |= payload[index + i] << (kByte * i);
  }
  return value;
}

}  // namespace touchraw
