// 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_ACPI_MULTIPLY_CONTROLLER_ACPI_SERVER_H_
#define FUCHSIA_SDK_EXAMPLES_ACPI_MULTIPLY_CONTROLLER_ACPI_SERVER_H_

#include <fidl/fuchsia.hardware.acpi/cpp/wire.h>
#include <lib/driver/component/cpp/logger.h>
#include <lib/mmio/mmio-buffer.h>

namespace acpi_multiply {

// FIDL server implementation for the `fuchsia.hardware.acpi/Device` protocol
class AcpiDeviceServer : public fidl::WireServer<fuchsia_hardware_acpi::Device> {
 public:
  AcpiDeviceServer(zx::interrupt irq, fdf::MmioBuffer buffer, driver::Logger* logger,
                   async_dispatcher_t* dispatcher)
      : irq_(std::move(irq)),
        buffer_(std::move(buffer)),
        logger_(logger),
        dispatcher_(dispatcher) {}

  static fidl::ServerBindingRef<fuchsia_hardware_acpi::Device> BindDeviceClient(
      std::shared_ptr<AcpiDeviceServer> server_impl, async_dispatcher_t* dispatcher,
      fidl::ServerEnd<fuchsia_hardware_acpi::Device> request);

  void OnUnbound(fidl::UnbindInfo info, fidl::ServerEnd<fuchsia_hardware_acpi::Device> server_end);

  // fidl::WireServer<fuchsia_hardware_acpi::Device>

  void MapInterrupt(MapInterruptRequestView request,
                    MapInterruptCompleter::Sync& completer) override;

  void GetMmio(GetMmioRequestView request, GetMmioCompleter::Sync& completer) override;

  void EvaluateObject(EvaluateObjectRequestView request,
                      EvaluateObjectCompleter::Sync& completer) override;

  void GetBusId(GetBusIdCompleter::Sync& completer) override {
    completer.ReplyError(ZX_ERR_BAD_STATE);
  }

  void GetPio(GetPioRequestView request, GetPioCompleter::Sync& completer) override {
    completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
  }
  void GetBti(GetBtiRequestView request, GetBtiCompleter::Sync& completer) override {
    completer.ReplyError(ZX_ERR_NOT_SUPPORTED);
  }

  void InstallNotifyHandler(InstallNotifyHandlerRequestView request,
                            InstallNotifyHandlerCompleter::Sync& completer) override {
    completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotImplemented);
  }

  void RemoveNotifyHandler(RemoveNotifyHandlerCompleter::Sync& completer) override {
    completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotImplemented);
  }

  void AcquireGlobalLock(AcquireGlobalLockCompleter::Sync& completer) override {
    completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotImplemented);
  }

  void InstallAddressSpaceHandler(InstallAddressSpaceHandlerRequestView request,
                                  InstallAddressSpaceHandlerCompleter::Sync& completer) override {
    completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotImplemented);
  }

  void SetWakeDevice(SetWakeDeviceRequestView request,
                     SetWakeDeviceCompleter::Sync& completer) override {
    completer.ReplyError(fuchsia_hardware_acpi::wire::Status::kNotImplemented);
  }

 private:
  zx::interrupt irq_;
  fdf::MmioBuffer buffer_;
  driver::Logger* logger_;
  async_dispatcher_t* dispatcher_;
};

}  // namespace acpi_multiply

#endif  // FUCHSIA_SDK_EXAMPLES_ACPI_MULTIPLY_CONTROLLER_ACPI_SERVER_H_
