// Copyright 2017 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 LIB_ASYNC_CPP_RECEIVER_H_
#define LIB_ASYNC_CPP_RECEIVER_H_

#include <lib/async/receiver.h>
#include <lib/fit/function.h>

#include <utility>

namespace async {

// Holds content for a packet receiver and its handler.
//
// After successfully queuing packets to the receiver, the client is responsible
// for retaining the structure in memory (and unmodified) until all packets have
// been received by the handler or the dispatcher shuts down.  There is no way
// to cancel a packet which has been queued.
//
// Multiple packets may be delivered to the same receiver concurrently.
//
// Concrete implementations: |async::Receiver|, |async::ReceiverMethod|.
// Please do not create subclasses of ReceiverBase outside of this library.
class ReceiverBase {
 protected:
  explicit ReceiverBase(async_receiver_handler_t* handler);
  ~ReceiverBase();

  ReceiverBase(const ReceiverBase&) = delete;
  ReceiverBase(ReceiverBase&&) = delete;
  ReceiverBase& operator=(const ReceiverBase&) = delete;
  ReceiverBase& operator=(ReceiverBase&&) = delete;

 public:
  // Enqueues a packet of data for delivery to a receiver.
  //
  // The |data| will be copied into the packet.  May be NULL to create a
  // zero-initialized packet payload.
  //
  // Returns |ZX_OK| if the packet was successfully enqueued.
  // Returns |ZX_ERR_BAD_STATE| if the dispatcher is shutting down.
  // Returns |ZX_ERR_NOT_SUPPORTED| if not supported by the dispatcher.
  zx_status_t QueuePacket(async_dispatcher_t* dispatcher, const zx_packet_user_t* data = nullptr);

 protected:
  template <typename T>
  static T* Dispatch(async_receiver_t* receiver) {
    static_assert(offsetof(ReceiverBase, receiver_) == 0, "");
    auto self = reinterpret_cast<ReceiverBase*>(receiver);
    return static_cast<T*>(self);
  }

 private:
  async_receiver_t receiver_;
};

// A receiver whose handler is bound to a |async::Task::Handler| function.
//
// Prefer using |async::ReceiverMethod| instead for binding to a fixed class member
// function since it is more efficient to dispatch.
class Receiver final : public ReceiverBase {
 public:
  // Handles receipt of packets containing user supplied data.
  //
  // The |status| is |ZX_OK| if the packet was successfully delivered and |data|
  // contains the information from the packet, otherwise |data| is null.
  using Handler = fit::function<void(async_dispatcher_t* dispatcher, async::Receiver* receiver,
                                     zx_status_t status, const zx_packet_user_t* data)>;

  explicit Receiver(Handler handler = nullptr);
  ~Receiver();

  void set_handler(Handler handler) { handler_ = std::move(handler); }
  bool has_handler() const { return !!handler_; }

 private:
  static void CallHandler(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
                          zx_status_t status, const zx_packet_user_t* data);

  Handler handler_;
};

// A receiver whose handler is bound to a fixed class member function.
//
// Usage:
//
// class Foo {
//     void Handle(async_dispatcher_t* dispatcher, async::ReceiverBase* receiver, zx_status_t
//     status,
//                 const zx_packet_user_t* data) { ... }
//     async::ReceiverMethod<Foo, &Foo::Handle> receiver_{this};
// };
template <class Class,
          void (Class::*method)(async_dispatcher_t* dispatcher, async::ReceiverBase* receiver,
                                zx_status_t status, const zx_packet_user_t* data)>
class ReceiverMethod final : public ReceiverBase {
 public:
  explicit ReceiverMethod(Class* instance)
      : ReceiverBase(&ReceiverMethod::CallHandler), instance_(instance) {}

 private:
  static void CallHandler(async_dispatcher_t* dispatcher, async_receiver_t* receiver,
                          zx_status_t status, const zx_packet_user_t* data) {
    auto self = Dispatch<ReceiverMethod>(receiver);
    (self->instance_->*method)(dispatcher, self, status, data);
  }

  Class* const instance_;
};

}  // namespace async

#endif  // LIB_ASYNC_CPP_RECEIVER_H_
