// 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_t on 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;

  // 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());
  }

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