// 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 prevously 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 prevously 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_
