// 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_DEVICES_BIN_DRIVER_HOST_ASYNC_LOOP_REF_COUNTED_RPC_HANDLER_H_
#define SRC_DEVICES_BIN_DRIVER_HOST_ASYNC_LOOP_REF_COUNTED_RPC_HANDLER_H_

#include <lib/async/cpp/wait.h>
#include <lib/zx/channel.h>

#include <utility>

#include <fbl/ref_ptr.h>

// Mixin for representing a type that represents an RPC handler and that has a
// reference owned by an async loop.  The loop will own both the wrapped type and the RPC
// connection handle.
//
// Deriving classes should define and implement this function:
// static void HandleRpc(fbl::RefPtr<T>&& conn,
//                       async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
//                       const zx_packet_signal_t* signal);
template <typename T>
class AsyncLoopRefCountedRpcHandler {
 public:
  ~AsyncLoopRefCountedRpcHandler() {
    zx_status_t status = wait_.Cancel();
    ZX_ASSERT(status == ZX_OK || status == ZX_ERR_NOT_FOUND);

    zx_handle_close(wait_.object());
  }

  // Begins waiting in |dispatcher| on |conn->wait|.  This transfers ownership
  // of a reference to |conn| to the dispatcher.  The dispatcher returns ownership when the
  // handler is invoked.
  static zx_status_t BeginWait(fbl::RefPtr<T> conn, async_dispatcher_t* dispatcher) {
    zx_status_t status = conn->wait_.Begin(dispatcher);
    if (status == ZX_OK) {
      // This reference will be recovered by MakeRefPtrNoAdopt in
      // HandleRpcEntry
      __UNUSED auto ptr = fbl::ExportToRawPtr(&conn);
    }
    return status;
  }

  // Entrypoint for the RPC handler that captures the pointer ownership
  // semantics.
  void HandleRpcEntry(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                      const zx_packet_signal_t* signal) {
    auto self = fbl::ImportFromRawPtr(static_cast<T*>(this));
    T::HandleRpc(std::move(self), dispatcher, wait, status, signal);
  }

  zx::unowned_channel channel() const { return zx::unowned_channel(wait_.object()); }

  // Sets the channel to the given handle and returns the old value
  zx::channel set_channel(zx::channel h) {
    zx::channel old(wait_.object());
    wait_.set_object(h.release());
    return old;
  }

  using WaitType = async::WaitMethod<AsyncLoopRefCountedRpcHandler<T>,
                                     &AsyncLoopRefCountedRpcHandler<T>::HandleRpcEntry>;

 private:
  WaitType wait_{this, ZX_HANDLE_INVALID, ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED};
};

#endif  // SRC_DEVICES_BIN_DRIVER_HOST_ASYNC_LOOP_REF_COUNTED_RPC_HANDLER_H_
