// 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/input/lib/hid-input-report/keyboard.h"

#include <lib/hid-parser/parser.h>
#include <lib/hid-parser/report.h>
#include <lib/hid-parser/units.h>
#include <lib/hid-parser/usages.h>
#include <lib/hid/usages.h>
#include <lib/stdcompat/span.h>
#include <stdint.h>

#include "src/ui/input/lib/hid-input-report/device.h"

namespace hid_input_report {

namespace {

std::optional<fuchsia::input::Key> hid_key_to_fuchsia_key3(hid::Usage usage) {
  if (usage.page == hid::usage::Page::kKeyboardKeypad) {
    auto code = (((uint8_t)(hid::usage::Page::kKeyboardKeypad)) & 0xFF) << 16 | (usage.usage);
    if (code == ((uint32_t)fuchsia::input::Key::KEYPAD_EQUALS) ||
        code == ((uint32_t)fuchsia::input::Key::MENU) ||
        (code >= ((uint32_t)fuchsia::input::Key::A) &&
         code <= ((uint32_t)fuchsia::input::Key::NON_US_BACKSLASH)) ||
        (code >= ((uint32_t)fuchsia::input::Key::LEFT_CTRL) &&
         (code <= ((uint32_t)fuchsia::input::Key::RIGHT_META)))) {
      return static_cast<fuchsia::input::Key>(code);
    }
  }
  return {};
}

void InsertFuchsiaKey3(uint32_t hid_usage, uint32_t hid_key,
                       std::set<fuchsia_input::wire::Key>* key_values) {
  std::optional<fuchsia::input::Key> fuchsia_key3 =
      hid_key_to_fuchsia_key3(hid::USAGE(hid_usage, hid_key));
  if (fuchsia_key3) {
    // Cast the key enum from HLCPP to LLCPP. We are guaranteed that this will be
    // equivalent.
    key_values->insert(static_cast<fuchsia_input::wire::Key>(*fuchsia_key3));
  }
}

}  // namespace

ParseResult Keyboard::ParseInputReportDescriptor(
    const hid::ReportDescriptor& hid_report_descriptor) {
  // Use a set to make it easy to create a list of sorted and unique keys.
  std::set<fuchsia_input::wire::Key> key_3_values;
  std::array<hid::ReportField, fuchsia_input_report::wire::kKeyboardMaxNumKeys> key_fields;
  size_t num_key_fields = 0;

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

    if (field.attr.usage.page == hid::usage::Page::kKeyboardKeypad) {
      if (field.flags & hid::FieldTypeFlags::kArray) {
        for (uint8_t key = static_cast<uint8_t>(field.attr.logc_mm.min);
             key < static_cast<uint8_t>(field.attr.logc_mm.max); key++) {
          InsertFuchsiaKey3(field.attr.usage.page, key, &key_3_values);
        }
      } else {
        InsertFuchsiaKey3(field.attr.usage.page, field.attr.usage.usage, &key_3_values);
      }

      key_fields[num_key_fields++] = field;
      if (num_key_fields == fuchsia_input_report::wire::kKeyboardMaxNumKeys) {
        return ParseResult::kTooManyItems;
      }
    }
  }

  if (key_3_values_.size() >= fuchsia_input_report::wire::kKeyboardMaxNumKeys) {
    return ParseResult::kTooManyItems;
  }

  // No error, write to class members.
  key_3_values_ = std::move(key_3_values);

  num_key_fields_ = num_key_fields;
  key_fields_ = key_fields;

  input_report_size_ = hid_report_descriptor.input_byte_sz;
  input_report_id_ = hid_report_descriptor.report_id;

  return ParseResult::kOk;
}

ParseResult Keyboard::ParseOutputReportDescriptor(
    const hid::ReportDescriptor& hid_report_descriptor) {
  std::array<hid::ReportField, fuchsia_input_report::wire::kKeyboardMaxNumLeds> led_fields;
  size_t num_leds = 0;

  for (size_t i = 0; i < hid_report_descriptor.output_count; i++) {
    const hid::ReportField& field = hid_report_descriptor.output_fields[i];
    if (field.attr.usage.page == hid::usage::Page::kLEDs) {
      if (num_leds == fuchsia_input_report::wire::kKeyboardMaxNumLeds) {
        return ParseResult::kTooManyItems;
      }
      led_fields[num_leds++] = field;
    }
  }

  if (num_leds == 0) {
    return ParseResult::kOk;
  }

  // No errors, write to class members.
  num_leds_ = num_leds;
  led_fields_ = led_fields;

  output_report_id_ = hid_report_descriptor.report_id;
  output_report_size_ = hid_report_descriptor.output_byte_sz;

  return ParseResult::kOk;
}

ParseResult Keyboard::ParseReportDescriptor(const hid::ReportDescriptor& hid_report_descriptor) {
  ParseResult res = ParseInputReportDescriptor(hid_report_descriptor);
  if (res != ParseResult::kOk) {
    return res;
  }
  return ParseOutputReportDescriptor(hid_report_descriptor);
}

ParseResult Keyboard::CreateDescriptor(fidl::AnyArena& allocator,
                                       fuchsia_input_report::wire::DeviceDescriptor& descriptor) {
  fuchsia_input_report::wire::KeyboardDescriptor keyboard(allocator);

  // Input Descriptor parsing.
  if (input_report_size_ > 0) {
    fuchsia_input_report::wire::KeyboardInputDescriptor keyboard_input(allocator);

    size_t keys_3_index = 0;
    fidl::VectorView<fuchsia_input::wire::Key> keys_3(allocator, key_3_values_.size());
    for (auto& key : key_3_values_) {
      keys_3[keys_3_index++] = key;
    }

    keyboard_input.set_keys3(allocator, std::move(keys_3));
    keyboard.set_input(allocator, std::move(keyboard_input));
  }

  // Output Descriptor parsing.
  if (output_report_size_ > 0) {
    fuchsia_input_report::wire::KeyboardOutputDescriptor keyboard_output(allocator);

    size_t leds_index = 0;
    fidl::VectorView<fuchsia_input_report::wire::LedType> leds(allocator, num_leds_);
    for (hid::ReportField& field : cpp20::span(led_fields_.data(), num_leds_)) {
      zx_status_t status = HidLedUsageToLlcppLedType(
          static_cast<hid::usage::LEDs>(field.attr.usage.usage), &leds[leds_index++]);
      if (status != ZX_OK) {
        return ParseResult::kBadReport;
      }
    }

    keyboard_output.set_leds(allocator, std::move(leds));
    keyboard.set_output(allocator, std::move(keyboard_output));
  }

  descriptor.set_keyboard(allocator, std::move(keyboard));
  return ParseResult::kOk;
}

ParseResult Keyboard::ParseInputReportInternal(
    const uint8_t* data, size_t len, fidl::AnyArena& allocator,
    fuchsia_input_report::wire::InputReport& input_report) {
  if (len != input_report_size_) {
    return ParseResult::kReportSizeMismatch;
  }

  fuchsia_input_report::wire::KeyboardInputReport keyboard_report(allocator);

  size_t num_pressed_keys_3 = 0;
  std::array<fuchsia_input::wire::Key, fuchsia_input_report::wire::kKeyboardMaxNumKeys>
      pressed_keys_3;
  for (hid::ReportField& field : cpp20::span(key_fields_.data(), num_key_fields_)) {
    double val_out_double;
    if (!ExtractAsUnitType(data, len, field.attr, &val_out_double)) {
      continue;
    }

    uint32_t val_out = static_cast<uint32_t>(val_out_double);
    if (val_out == 0) {
      continue;
    }

    // Get the HID key.
    uint32_t hid_key;
    if (field.flags & hid::FieldTypeFlags::kArray) {
      if (val_out == HID_USAGE_KEY_ERROR_ROLLOVER) {
        return ParseResult::kBadReport;
      }
      hid_key = val_out;
    } else {
      hid_key = field.attr.usage.usage;
    }

    // Convert to fuchsia key.
    auto fuchsia_key_3 =
        hid_key_to_fuchsia_key3(hid::USAGE(hid::usage::Page::kKeyboardKeypad, hid_key));
    if (fuchsia_key_3) {
      // Cast the key enum from HLCPP to LLCPP. We are guaranteed that this will be equivalent.
      pressed_keys_3[num_pressed_keys_3++] = static_cast<fuchsia_input::wire::Key>(*fuchsia_key_3);
    }
  }

  fidl::VectorView<fuchsia_input::wire::Key> fidl_pressed_keys_3(allocator, num_pressed_keys_3);
  for (size_t i = 0; i < num_pressed_keys_3; i++) {
    fidl_pressed_keys_3[i] = pressed_keys_3[i];
  }

  keyboard_report.set_pressed_keys3(allocator, std::move(fidl_pressed_keys_3));

  input_report.set_keyboard(allocator, std::move(keyboard_report));
  return ParseResult::kOk;
}

ParseResult Keyboard::SetOutputReportInternal(
    const fuchsia_input_report::wire::OutputReport* report, uint8_t* data, size_t data_size,
    size_t* data_out_size) {
  if (!report->has_keyboard()) {
    return ParseResult::kNotImplemented;
  }
  if (!report->keyboard().has_enabled_leds()) {
    return ParseResult::kNotImplemented;
  }
  if (data_size < output_report_size_) {
    return ParseResult::kNoMemory;
  }
  for (size_t i = 0; i < data_size; i++) {
    data[i] = 0;
  }
  // Go through each enabled LED and set its report field to enabled.
  for (fuchsia_input_report::wire::LedType led : report->keyboard().enabled_leds()) {
    bool found = false;
    for (size_t i = 0; i < num_leds_; i++) {
      hid::ReportField& hid_led = led_fields_[i];
      // Convert the usage to LedType.
      fuchsia_input_report::wire::LedType hid_led_type;
      zx_status_t status = HidLedUsageToLlcppLedType(
          static_cast<hid::usage::LEDs>(hid_led.attr.usage.usage), &hid_led_type);
      if (status != ZX_OK) {
        return ParseResult::kBadReport;
      }
      if (hid_led_type == led) {
        found = true;
        if (!InsertAsUnitType(data, data_size, hid_led.attr, 1)) {
          return ParseResult::kBadReport;
        }
        break;
      }
    }
    if (!found) {
      return ParseResult::kItemNotFound;
    }
  }
  *data_out_size = output_report_size_;
  return ParseResult::kOk;
}

}  // namespace hid_input_report
