// 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 SRC_ACPI_MULTIPLY_ACPI_CONTROLLER_H_
#define SRC_ACPI_MULTIPLY_ACPI_CONTROLLER_H_

#include <fidl/fuchsia.driver.framework/cpp/markers.h>
#include <fidl/fuchsia.driver.framework/cpp/wire_types.h>
#include <fidl/fuchsia.hardware.acpi/cpp/wire.h>
#include <lib/driver2/logger.h>
#include <lib/driver2/namespace.h>
#include <lib/fdf/cpp/dispatcher.h>
#include <lib/mmio/mmio-buffer.h>
#include <lib/sys/component/llcpp/outgoing_directory.h>
#include <lib/zx/status.h>

namespace acpi_multiply {

// Sample driver that implements a `fuchsia.hardware.acpi` bus controller and emulates the
// following ACPI protocol behaviors for the ACPI multiple driver:
// 1. Child driver writes two values to multiply to register offsets 0x0 and 0x04
// 2. Child driver calls EvaluateObject("_MUL") to perform the multiplication, and waits
// for an interrupt.
// 3. This driver performs the multiplication, writes the result (64-bit) to 0x08
// and triggers an interrupt.
class AcpiMultiplyController : public fidl::WireServer<fuchsia_hardware_acpi::Device> {
 public:
  AcpiMultiplyController(async_dispatcher_t* dispatcher,
                         fidl::WireSharedClient<fuchsia_driver_framework::Node> node,
                         driver::Namespace ns, driver::Logger logger)
      : dispatcher_(dispatcher),
        outgoing_(component::OutgoingDirectory::Create(dispatcher)),
        ns_(std::move(ns)),
        logger_(std::move(logger)),
        node_(std::move(node)) {}

  virtual ~AcpiMultiplyController() = default;

  static constexpr const char* Name() { return "sample-acpi-controller"; }
  static zx::status<std::unique_ptr<AcpiMultiplyController>> Start(
      fuchsia_driver_framework::wire::DriverStartArgs& start_args,
      fdf::UnownedDispatcher dispatcher,
      fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns,
      driver::Logger logger);

  // fuchsia.hardware.acpi/Device:
  void MapInterrupt(MapInterruptRequestView request, MapInterruptCompleter::Sync& completer);
  void GetMmio(GetMmioRequestView request, GetMmioCompleter::Sync& completer);
  void EvaluateObject(EvaluateObjectRequestView request, EvaluateObjectCompleter::Sync& completer);

  void GetBusId(GetBusIdRequestView request, GetBusIdCompleter::Sync& completer) {
    completer.ReplyError(ZX_ERR_BAD_STATE);
  }

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

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

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

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

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

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

 private:
  zx::status<> Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir);
  zx::status<> AddChild();

  async_dispatcher_t* const dispatcher_;
  component::OutgoingDirectory outgoing_;
  driver::Namespace ns_;
  driver::Logger logger_;

  zx::interrupt irq_;

  std::optional<fdf::MmioBuffer> buffer_;

  fidl::WireSharedClient<fuchsia_driver_framework::Node> node_;
  fidl::WireSharedClient<fuchsia_driver_framework::NodeController> controller_;
};

}  // namespace acpi_multiply

#endif  // SRC_ACPI_MULTIPLY_ACPI_CONTROLLER_H_
