// Copyright 2022 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 FUCHSIA_SDK_EXAMPLES_INPUT_SAMPLE_INPUT_SERVER_H_
#define FUCHSIA_SDK_EXAMPLES_INPUT_SAMPLE_INPUT_SERVER_H_

#include <fidl/fuchsia.input.report/cpp/wire.h>
#include <lib/driver/component/cpp/logger.h>
#include <lib/input_report_reader/reader.h>

namespace input_sample {

constexpr uint8_t kMouseButtonCount = 3;

// Used by the input report reader library to transform reports over FIDL
struct SampleInputReport {
  zx::time event_time;
  uint8_t buttons = 0;
  int8_t rel_x = 0;
  int8_t rel_y = 0;

  void ToFidlInputReport(
      fidl::WireTableBuilder<::fuchsia_input_report::wire::InputReport>& input_report,
      fidl::AnyArena& arena);
};

// FIDL server implementation for the `fuchsia.input.report/InputDevice` protocol
class InputSampleServer : public fidl::WireServer<fuchsia_input_report::InputDevice> {
 public:
  InputSampleServer(driver::Logger* logger, async_dispatcher_t* dispatcher,
                    std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
                        input_report_readers)
      : logger_(logger), dispatcher_(dispatcher), input_report_readers_(input_report_readers) {}

  static fidl::ServerBindingRef<fuchsia_input_report::InputDevice> BindDeviceClient(
      driver::Logger* logger, async_dispatcher_t* dispatcher,
      std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
          input_report_readers,
      fidl::ServerEnd<fuchsia_input_report::InputDevice> request);

  void OnUnbound(fidl::UnbindInfo info,
                 fidl::ServerEnd<fuchsia_input_report::InputDevice> server_end);

  // fidl::WireServer<fuchsia_input_report::InputDevice>

  void GetInputReportsReader(GetInputReportsReaderRequestView request,
                             GetInputReportsReaderCompleter::Sync& completer) override;

  void GetDescriptor(GetDescriptorCompleter::Sync& completer) override;

  void SendOutputReport(SendOutputReportRequestView request,
                        SendOutputReportCompleter::Sync& completer) override {
    completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
  }
  void GetFeatureReport(GetFeatureReportCompleter::Sync& completer) override {
    completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
  }
  void SetFeatureReport(SetFeatureReportRequestView request,
                        SetFeatureReportCompleter::Sync& completer) override {
    completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
  }
  void GetInputReport(GetInputReportRequestView request,
                      GetInputReportCompleter::Sync& completer) override {
    completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
  }

 private:
  driver::Logger* logger_;
  async_dispatcher_t* const dispatcher_;
  std::weak_ptr<input_report_reader::InputReportReaderManager<SampleInputReport>>
      input_report_readers_;
};

}  // namespace input_sample

#endif  // FUCHSIA_SDK_EXAMPLES_INPUT_SAMPLE_INPUT_SERVER_H_
