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

#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fidl/cpp/internal/stub_controller.h>
#include <lib/fit/function.h>
#include <lib/zx/channel.h>
#include <zircon/assert.h>

#include <memory>
#include <utility>

namespace fidl {

// Binds the implementation of |Interface| to a channel.
//
// The |Binding| listens for incoming messages on the channel, decodes them, and
// calls the appropriate method on the bound implementation. If the message
// expects a reply, the |Binding| creates callbacks that encode and send
// reply messages when called.
//
// When the |Binding| object is destroyed, the binding between the channel
// and the interface is torn down and the channel is closed, leaving the
// |Binding| in an unbound state.
//
// The implementation pointer type of the binding is also parameterized,
// allowing the use of smart pointer types such as |std::unique_ptr| to
// reference the implementation.
//
// Example:
//
//   #include "foo.fidl.h"
//
//   class FooImpl : public Foo {
//    public:
//     explicit FooImpl(InterfaceRequest<Foo> request)
//         : binding_(this, std::move(request)) {}
//
//     // Foo implementation here.
//
//    private:
//     Binding<Foo> binding_;
//   };
//
// After the |Binding| has been bound to an implementation, the implementation
// will receive methods calls from the remote endpoint of the channel on the
// async_dispatcher_t to which the |InterfaceRequest| was bound. By default this
// is the thread on which the binding occurred.
//
// See also:
//
//  * |InterfacePtr|, which is the client analog of a |Binding|.
//  * |EventSender|, which can send messages from multiple threads safely.
template <typename Interface, typename ImplPtr = Interface*>
class Binding final {
 private:
  template <class T>
  struct is_unique_ptr : std::false_type {};

  template <class T, class D>
  struct is_unique_ptr<std::unique_ptr<T, D>> : std::true_type {};

  template <class T>
  struct is_shared_ptr : std::false_type {};

  template <class T>
  struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};

  static_assert(std::is_pointer<ImplPtr>::value || is_unique_ptr<ImplPtr>::value ||
                    is_shared_ptr<ImplPtr>::value,
                "Binding only supports ImplPtr which are pointers");

 public:
  // Constructs an incomplete binding that will use the implementation |impl|.
  //
  // The binding may be completed with a subsequent call to the |Bind| method.
  // Does not take ownership of |impl|, which must outlive the binding.
  explicit Binding(ImplPtr impl) : impl_(std::forward<ImplPtr>(impl)), stub_(&*this->impl()) {
    controller_.set_stub(&stub_);
    stub_.set_sender(&controller_);
  }

  // Constructs a completed binding of |channel| to implementation |impl|.
  //
  // Does not take ownership of |impl|, which must outlive the binding.
  //
  // If the |Binding| cannot be bound to the given |channel| (e.g., because
  // the |channel| lacks |ZX_RIGHT_WAIT|), the |Binding| will be constructed
  // in an unbound state.
  //
  // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
  // messages from the channel and to monitor the channel for
  // |ZX_CHANNEL_PEER_CLOSED|.  If |dispatcher| is null, the current thread must
  // have a default async_dispatcher_t.
  Binding(ImplPtr impl, zx::channel channel, async_dispatcher_t* dispatcher = nullptr)
      : Binding(std::forward<ImplPtr>(impl)) {
    Bind(std::move(channel), dispatcher);
  }

  // Constructs a completed binding of |impl| to the channel in |request|.
  //
  // Does not take ownership of |impl|, which must outlive the binding.
  //
  // If the |Binding| cannot be bound to the given |channel| (e.g., because
  // the |channel| lacks |ZX_RIGHT_WAIT|), the |Binding| will be constructed
  // in an unbound state.
  //
  // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
  // messages from the channel and to monitor the channel for
  // |ZX_CHANNEL_PEER_CLOSED|.  If |dispatcher| is null, the current thread must
  // have a default async_dispatcher_t.
  Binding(ImplPtr impl, InterfaceRequest<Interface> request,
          async_dispatcher_t* dispatcher = nullptr)
      : Binding(std::forward<ImplPtr>(impl)) {
    Bind(request.TakeChannel(), dispatcher);
  }

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

  // The implementation of this class provides external references to class members via pointers.
  // As a result, instances cannot be move-constructed or move-assigned.
  Binding(Binding&&) = delete;
  Binding& operator=(Binding&&) = delete;

  // Completes a binding by creating a new channel, binding one endpoint to
  // the previously specified implementation and returning the other endpoint.
  //
  // If |NewBinding| fails to create the underlying channel, the returned
  // |InterfaceHandle| will return false from |is_valid()|.
  //
  // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
  // messages from the channel and to monitor the channel for
  // |ZX_CHANNEL_PEER_CLOSED|.  If |dispatcher| is null, the current thread must
  // have a default async_dispatcher_t.
  InterfaceHandle<Interface> NewBinding(async_dispatcher_t* dispatcher = nullptr) {
    InterfaceHandle<Interface> client;
    Bind(client.NewRequest().TakeChannel(), dispatcher);
    return client;
  }

  // Binds the previously specified implementation to the given |channel|.
  //
  // If the |Binding| was previously bound to another channel, that channel is
  // closed.
  //
  // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
  // messages from the channel and to monitor the channel for
  // |ZX_CHANNEL_PEER_CLOSED|.  If |dispatcher| is null, the current thread must
  // have a default async_dispatcher_t.
  //
  // Returns an error if the binding was not able to be created (e.g., because
  // the |channel| lacks |ZX_RIGHT_WAIT|).
  zx_status_t Bind(zx::channel channel, async_dispatcher_t* dispatcher = nullptr) {
    return controller_.reader().Bind(std::move(channel), dispatcher);
  }

  // Binds the previously specified implementation to the given
  // |InterfaceRequest|.
  //
  // If the |Binding| was previously bound to another channel, that channel is
  // closed.
  //
  // Uses the given async_dispatcher_t (e.g., a message loop) in order to read
  // messages from the channel and to monitor the channel for
  // |ZX_CHANNEL_PEER_CLOSED|.  If |dispatcher| is null, the current thread must
  // have a default async_dispatcher_t.
  //
  // Returns an error if the binding was not able to be created (e.g., because
  // the |channel| lacks |ZX_RIGHT_WAIT|).
  zx_status_t Bind(InterfaceRequest<Interface> request, async_dispatcher_t* dispatcher = nullptr) {
    return Bind(request.TakeChannel(), dispatcher);
  }

  // Unbinds the underlying channel from this binding and returns it so it can
  // be used in another context, such as on another thread or with a different
  // implementation.
  //
  // After this function returns, the |Binding| is ready to be bound to another
  // channel.
  InterfaceRequest<Interface> Unbind() {
    return InterfaceRequest<Interface>(controller_.reader().Unbind());
  }

  // Sends an Epitaph over the bound channel corresponding to the error passed
  // as a parameter, closes the channel, and unbinds it.  An Epitaph is the last
  // message sent over a channel before a close operation; for the purposes of
  // this function, it can be thought of as a return code.  See the FIDL
  // language spec for more information about Epitaphs.
  //
  // The return value can be any of the return values of zx_channel_write.
  zx_status_t Close(zx_status_t epitaph_value) { return controller_.reader().Close(epitaph_value); }

  // Blocks the calling thread until either a message arrives on the previously
  // bound channel or an error occurs.
  //
  // Returns an error if waiting for the message, reading the message, or
  // processing the message fails. If the error results in the channel being
  // closed, the error handler will be called synchronously before this
  // method returns.
  //
  // This method can be called only if this |Binding| is currently bound to a
  // channel.
  zx_status_t WaitForMessage() {
    return controller_.reader().WaitAndDispatchOneMessageUntil(zx::time::infinite());
  }

  // Whether an error handler has been set.
  //
  // See |set_error_handler()|.
  constexpr bool has_error_handler() const { return controller_.reader().has_error_handler(); }

  // Sets an error handler that will be called if an error causes the underlying
  // channel to be closed.
  //
  // If the error is being reported because an error occurred on the local side
  // of the channel, the zx_status_t of that error will be passed as the
  // parameter to the handler.
  //
  // For example, the error handler will be called if the remote side of the
  // channel sends an invalid message. When the error handler is called, the
  // |Binding| will no longer be bound to the channel.
  void set_error_handler(fit::function<void(zx_status_t)> error_handler) {
    controller_.reader().set_error_handler(std::move(error_handler));
  }

  // The implementation used by this |Binding| to process incoming messages.
  const ImplPtr& impl() const { return impl_; }

  // The interface for sending events back to the client.
  typename Interface::EventSender_& events() { return stub_; }

  // Whether this |Binding| is currently listening to a channel.
  bool is_bound() const { return controller_.reader().is_bound(); }

  // The underlying channel.
  const zx::channel& channel() const { return controller_.reader().channel(); }

  // The |async_dispatcher_t| to which this binding is bound, if any.
  async_dispatcher_t* dispatcher() const { return controller_.reader().dispatcher(); }

 private:
  const ImplPtr impl_;
  typename Interface::Stub_ stub_;
  internal::StubController controller_;
};

}  // namespace fidl

#endif  // LIB_FIDL_CPP_BINDING_H_
