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

#ifndef SRC_UI_INPUT_DRIVERS_HID_BUTTONS_HID_BUTTONS_H_
#define SRC_UI_INPUT_DRIVERS_HID_BUTTONS_HID_BUTTONS_H_

#include <fuchsia/buttons/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/sync/completion.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <lib/zx/interrupt.h>
#include <lib/zx/port.h>
#include <lib/zx/timer.h>

#include <list>
#include <map>
#include <optional>
#include <set>
#include <vector>

#include <ddk/metadata/buttons.h>
#include <ddk/protocol/buttons.h>
#include <ddk/protocol/gpio.h>
#include <ddktl/device.h>
#include <ddktl/fidl.h>
#include <ddktl/protocol/buttons.h>
#include <ddktl/protocol/hidbus.h>
#include <fbl/array.h>
#include <fbl/auto_lock.h>
#include <fbl/mutex.h>
#include <fbl/ref_counted.h>
#include <hid/buttons.h>

#include "lib/zx/channel.h"
#include "zircon/types.h"

namespace buttons {

// zx_port_packet::key.
constexpr uint64_t kPortKeyShutDown = 0x01;
// Start of up to kNumberOfRequiredGpios port types used for interrupts.
constexpr uint64_t kPortKeyInterruptStart = 0x10;
// Timer start
constexpr uint64_t kPortKeyTimerStart = 0x100;
// Debounce threshold.
constexpr uint64_t kDebounceThresholdNs = 50'000'000;

class HidButtonsDevice;
using DeviceType = ddk::Device<HidButtonsDevice, ddk::Unbindable>;
class HidButtonsHidBusFunction;
using HidBusFunctionType = ddk::Device<HidButtonsHidBusFunction, ddk::Unbindable>;
class HidButtonsButtonsFunction;
using ButtonsFunctionType = ddk::Device<HidButtonsButtonsFunction, ddk::Unbindable>;
class ButtonsNotifyInterface;

using Buttons = ::llcpp::fuchsia::buttons::Buttons;
using ButtonType = ::llcpp::fuchsia::buttons::ButtonType;

class HidButtonsDevice : public DeviceType {
 public:
  struct Gpio {
    gpio_protocol_t gpio;
    zx::interrupt irq;
    buttons_gpio_config_t config;
  };

  explicit HidButtonsDevice(zx_device_t* device) : DeviceType(device) {}
  virtual ~HidButtonsDevice() = default;

  // Hidbus Protocol Functions.
  zx_status_t HidbusStart(const hidbus_ifc_protocol_t* ifc) TA_EXCL(client_lock_);
  zx_status_t HidbusQuery(uint32_t options, hid_info_t* info);
  void HidbusStop() TA_EXCL(client_lock_);
  zx_status_t HidbusGetDescriptor(hid_description_type_t desc_type, void* out_data_buffer,
                                  size_t data_size, size_t* out_data_actual);
  zx_status_t HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len,
                              size_t* out_len) TA_EXCL(client_lock_);
  zx_status_t HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const void* data, size_t len);
  zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* duration);
  zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration);
  zx_status_t HidbusGetProtocol(uint8_t* protocol);
  zx_status_t HidbusSetProtocol(uint8_t protocol);

  // Buttons Protocol Functions.
  zx_status_t ButtonsGetChannel(zx::channel chan, async_dispatcher_t* dispatcher);

  // FIDL Interface Functions.
  bool GetState(ButtonType type);
  zx_status_t RegisterNotify(uint8_t types, ButtonsNotifyInterface* notify);

  void DdkUnbind(ddk::UnbindTxn txn);
  void DdkRelease();

  zx_status_t Bind(fbl::Array<Gpio> gpios, fbl::Array<buttons_button_config_t> buttons);
  virtual void ClosingChannel(ButtonsNotifyInterface* notify);
  virtual void Notify(uint32_t button_index);

 protected:
  // Protected for unit testing.
  void ShutDown() TA_EXCL(client_lock_);
  HidButtonsButtonsFunction* GetButtonsFunction() { return buttons_function_; }

  zx::port port_;

  fbl::Mutex channels_lock_;
  // A map of ButtonTypes to the interfaces that have to be notified when they are pressed.
  std::map<ButtonType, std::set<ButtonsNotifyInterface*>> registered_notifiers_
      TA_GUARDED(channels_lock_);
  // A map of ButtonType values to an index into the buttons_ array.
  std::map<ButtonType, uint32_t> button_map_;

  std::list<ButtonsNotifyInterface> interfaces_ TA_GUARDED(channels_lock_);  // owns the channels

  HidButtonsHidBusFunction* hidbus_function_;
  HidButtonsButtonsFunction* buttons_function_;

 private:
  friend class HidButtonsDeviceTest;

  int Thread();
  uint8_t ReconfigurePolarity(uint32_t idx, uint64_t int_port);
  zx_status_t ConfigureInterrupt(uint32_t idx, uint64_t int_port);
  bool MatrixScan(uint32_t row, uint32_t col, zx_duration_t delay);

  thrd_t thread_;
  fbl::Mutex client_lock_;
  ddk::HidbusIfcProtocolClient client_ TA_GUARDED(client_lock_);
  fbl::Array<buttons_button_config_t> buttons_;
  fbl::Array<Gpio> gpios_;

  struct debounce_state {
    bool enqueued;
    zx::timer timer;
    bool value;
  };
  fbl::Array<debounce_state> debounce_states_;
  // last_report_ saved to de-duplicate reports
  buttons_input_rpt_t last_report_;
};

class HidButtonsHidBusFunction
    : public HidBusFunctionType,
      public ddk::HidbusProtocol<HidButtonsHidBusFunction, ddk::base_protocol>,
      public fbl::RefCounted<HidButtonsHidBusFunction> {
 public:
  explicit HidButtonsHidBusFunction(zx_device_t* device, HidButtonsDevice* peripheral)
      : HidBusFunctionType(device), device_(peripheral) {}
  virtual ~HidButtonsHidBusFunction() = default;

  void DdkUnbind(ddk::UnbindTxn txn) { txn.Reply(); }
  void DdkRelease() { delete this; }

  // Methods required by the ddk mixins.
  zx_status_t HidbusStart(const hidbus_ifc_protocol_t* ifc) { return device_->HidbusStart(ifc); }
  zx_status_t HidbusQuery(uint32_t options, hid_info_t* info) {
    return device_->HidbusQuery(options, info);
  }
  void HidbusStop() { device_->HidbusStop(); }
  zx_status_t HidbusGetDescriptor(hid_description_type_t desc_type, void* out_data_buffer,
                                  size_t data_size, size_t* out_data_actual) {
    return device_->HidbusGetDescriptor(desc_type, out_data_buffer, data_size, out_data_actual);
  }
  zx_status_t HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, void* data, size_t len,
                              size_t* out_len) {
    return device_->HidbusGetReport(rpt_type, rpt_id, data, len, out_len);
  }
  zx_status_t HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const void* data, size_t len) {
    return device_->HidbusSetReport(rpt_type, rpt_id, data, len);
  }
  zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* duration) {
    return device_->HidbusGetIdle(rpt_id, duration);
  }
  zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration) {
    return device_->HidbusSetIdle(rpt_id, duration);
  }
  zx_status_t HidbusGetProtocol(uint8_t* protocol) { return device_->HidbusGetProtocol(protocol); }
  zx_status_t HidbusSetProtocol(uint8_t protocol) { return device_->HidbusSetProtocol(protocol); }

 private:
  HidButtonsDevice* device_;
};

class HidButtonsButtonsFunction
    : public ButtonsFunctionType,
      public ddk::ButtonsProtocol<HidButtonsButtonsFunction, ddk::base_protocol>,
      public fbl::RefCounted<HidButtonsButtonsFunction> {
 public:
  HidButtonsButtonsFunction(zx_device_t* device, HidButtonsDevice* peripheral)
      : ButtonsFunctionType(device),
        device_(peripheral),
        loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {
    loop_.StartThread("hid-buttons-notify-loop", &loop_thread_);
  }
  virtual ~HidButtonsButtonsFunction() = default;

  void DdkUnbind(ddk::UnbindTxn txn) {
    loop_.Shutdown();
    txn.Reply();
  }
  void DdkRelease() { delete this; }

  // Methods required by the ddk mixins.
  zx_status_t ButtonsGetChannel(zx::channel chan) {
    return device_->ButtonsGetChannel(std::move(chan), loop_.dispatcher());
  }

 private:
  HidButtonsDevice* device_;

  async::Loop loop_;
  thrd_t loop_thread_;
};

class ButtonsNotifyInterface : public Buttons::Interface {
 public:
  explicit ButtonsNotifyInterface(HidButtonsDevice* peripheral) : device_(peripheral) {}
  ~ButtonsNotifyInterface() = default;

  zx_status_t Init(async_dispatcher_t* dispatcher, zx::channel chan) {
    fidl::OnUnboundFn<ButtonsNotifyInterface> unbound = [this](ButtonsNotifyInterface*,
                                                               fidl::UnbindInfo, zx::channel) {
      device_->ClosingChannel(this);
    };
    auto res = fidl::BindServer(dispatcher, std::move(chan), this, std::move(unbound));
    if (res.is_error())
      return res.error();
    binding_ = res.take_value();
    return ZX_OK;
  }

  const fidl::ServerBindingRef<Buttons>& binding() { return *binding_; }

  // Methods required by the FIDL interface
  void GetState(ButtonType type, GetStateCompleter::Sync& _completer) {
    _completer.Reply(device_->GetState(type));
  }
  void RegisterNotify(uint8_t types, RegisterNotifyCompleter::Sync& _completer) {
    zx_status_t status = ZX_OK;
    if ((status = device_->RegisterNotify(types, this)) == ZX_OK) {
      _completer.ReplySuccess();
    } else {
      _completer.ReplyError(status);
    }
  }

 private:
  HidButtonsDevice* device_;
  std::optional<fidl::ServerBindingRef<Buttons>> binding_;
};

}  // namespace buttons

#endif  // SRC_UI_INPUT_DRIVERS_HID_BUTTONS_HID_BUTTONS_H_
