// Copyright 2019 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_LLCPP_SERVER_H_
#define LIB_FIDL_LLCPP_SERVER_H_

#include <lib/fidl/llcpp/async_binding.h>

namespace fidl {

// Forward declarations.
template <typename Protocol>
class ServerBindingRef;

template <typename Interface>
fit::result<ServerBindingRef<typename Interface::_EnclosingProtocol>, zx_status_t> BindServer(
    async_dispatcher_t* dispatcher, zx::channel channel, Interface* impl);
template <typename Interface>
fit::result<ServerBindingRef<typename Interface::_EnclosingProtocol>, zx_status_t> BindServer(
    async_dispatcher_t* dispatcher, zx::channel channel, Interface* impl,
    OnUnboundFn<Interface> on_unbound);
template <typename Interface>
fit::result<ServerBindingRef<typename Interface::_EnclosingProtocol>, zx_status_t> BindServer(
    async_dispatcher_t* dispatcher, zx::channel channel, std::unique_ptr<Interface> impl);

namespace internal {

// The interface for dispatching incoming FIDL messages. The code generator
// will provide conforming implementations for relevant FIDL protocols.
class IncomingMessageDispatcher {
 public:
  virtual ~IncomingMessageDispatcher() = default;

  // Dispatches an incoming message to one of the handlers functions in the
  // protocol. If there is no matching handler, closes all the handles in
  // |msg| and closes the channel with a |ZX_ERR_NOT_SUPPORTED| epitaph, before
  // returning false. The message should then be discarded.
  //
  // Note that the |dispatch_message| name avoids conflicts with FIDL method
  // names which would appear on the subclasses.
  //
  // Always consumes the handles in |msg|.
  virtual ::fidl::DispatchResult dispatch_message(fidl_incoming_msg_t* msg,
                                                  ::fidl::Transaction* txn) = 0;
};

template <typename Protocol>
fit::result<ServerBindingRef<Protocol>, zx_status_t> BindServerImpl(
    async_dispatcher_t* dispatcher, zx::channel channel, IncomingMessageDispatcher* interface,
    AnyOnUnboundFn on_unbound);

// Defines an incoming method entry. Used by a server to dispatch an incoming message.
struct MethodEntry {
  // The ordinal of the method handled by the entry.
  uint64_t ordinal;
  // The coding table of the method (used to decode the message).
  const fidl_type_t* type;
  // The function which handles the decoded message.
  void (*dispatch)(void* interface, void* bytes, ::fidl::Transaction* txn);
};

// The compiler generates an array of MethodEntry for each protocol.
// The TryDispatch method for each protocol calls this function using the generated entries, which
// searches through the array using the method ordinal to find the corresponding dispatch function.
::fidl::DispatchResult TryDispatch(void* impl, fidl_incoming_msg_t* msg, ::fidl::Transaction* txn,
                                   MethodEntry* begin, MethodEntry* end);

}  // namespace internal

// This class manages a server connection and its binding to an
// async_dispatcher_t* (which may be multi-threaded). See the detailed
// documentation on the |BindServer()| APIs below.
template <typename Protocol>
class ServerBindingRef {
 public:
  ~ServerBindingRef() = default;

  ServerBindingRef(ServerBindingRef&&) = default;
  ServerBindingRef& operator=(ServerBindingRef&&) = default;

  ServerBindingRef(const ServerBindingRef&) = default;
  ServerBindingRef& operator=(const ServerBindingRef&) = default;

  // Triggers an asynchronous unbind operation. If specified, |on_unbound| will be invoked on a
  // dispatcher thread, passing in the channel and the unbind reason. On return, the dispatcher
  // will no longer have any wait associated with the channel (though handling of any already
  // in-flight transactions will continue).
  //
  // This may be called from any thread.
  //
  // WARNING: While it is safe to invoke Unbind() from any thread, it is unsafe to wait on the
  // OnUnboundFn from a dispatcher thread, as that will likely deadlock.
  void Unbind() {
    if (auto binding = event_sender_.binding_.lock())
      binding->Unbind(std::move(binding));
  }

  // Triggers an asynchronous unbind operation. Eventually, the epitaph will be sent over the
  // channel which will be subsequently closed. If specified, |on_unbound| will be invoked giving
  // the unbind reason as an argument.
  //
  // This may be called from any thread.
  void Close(zx_status_t epitaph) {
    if (auto binding = event_sender_.binding_.lock())
      binding->Close(std::move(binding), epitaph);
  }

  // Return the interface for sending FIDL events. If the server has been unbound, calls on the
  // interface return error with status ZX_ERR_CANCELED.
  const typename Protocol::WeakEventSender* get() const { return &event_sender_; }
  const typename Protocol::WeakEventSender* operator->() const { return &event_sender_; }
  const typename Protocol::WeakEventSender& operator*() const { return event_sender_; }

 private:
  friend fit::result<ServerBindingRef<Protocol>, zx_status_t> internal::BindServerImpl<Protocol>(
      async_dispatcher_t* dispatcher, zx::channel channel,
      internal::IncomingMessageDispatcher* interface, internal::AnyOnUnboundFn on_unbound);

  explicit ServerBindingRef(std::weak_ptr<internal::AsyncServerBinding<Protocol>> internal_binding)
      : event_sender_(std::move(internal_binding)) {}

  typename Protocol::WeakEventSender event_sender_;
};

// Binds an implementation of a low-level C++ server interface to |channel| using a potentially
// multi-threaded |dispatcher|. This implementation allows for multiple in-flight synchronously or
// asynchronously handled transactions.
//
// This function adds an asynchronous wait to the given |dispatcher| for new messages to arrive on
// |channel|. When a message arrives, the dispatch function corresponding to the interface is called
// on one of the |dispatcher| threads.
//
// Typically, the dispatch function is generated by the low-level C++ backend for FIDL interfaces.
// These dispatch functions decode the |fidl_incoming_msg_t| and call into the implementation of the
// FIDL interface, via its C++ vtable.
//
// Creation:
// - Upon success |BindServer| creates a binding that owns |channel|. In this case, the binding is
//   initially kept alive even if the returned fit::result with a |ServerBindingRef| is ignored.
// - |ServerBindingRef| is a reference to the binding, it does not hold the binding. To unbind the
//   binding, see Unbind below.
// - Upon any error creating the binding, |BindServer| returns a fit::error and |channel| is closed.
//
// Destruction:
// - If the returned |ServerBindingRef| is ignored or dropped some time during the server operation,
//   then if some error occurs (see below) the binding will be automatically destroyed.
// - If the returned |ServerBindingRef| is kept but an error occurs (see below), the binding will be
//   destroyed, though calls may still be made on the |ServerBindingRef|.
// - On an error, |channel| is unbound from the dispatcher, i.e. no dispatcher threads will interact
//   with it. Calls on inflight |Transaction|s will have no effect. If |on_unbound| is not
//   specified, the |channel| is closed. If specified, |on_unbound| is then executed on a
//   |dispatcher| thread allowing the user to process the error. |on_unbound| includes the server
//   end of the channel as a parameter, if ignored the channel will be closed at the end of
//   |on_unbound|'s scope.
//
// Unbind:
// - The |ServerBindingRef| can be used to explicitly |Unbind| the binding and retrieve the
//   |channel| endpoint.
// - |Unbind| is non-blocking with respect to user code paths, i.e. if it blocks, it does so on
//   deterministic internal code paths. As such, the user may safely synchronize around an |Unbind|
//   call.
// - In order to reclaim the |channel|, the user must specify an |on_unbound| hook. This will be
//   invoked after the |channel| has been unbound from the |dispatcher|. The |channel| will be given
//   as an argument to the hook.
// - If the user shuts down the |dispatcher| prior to the |on_unbound| hook running, it may be
//   dropped instead.
//
// Close:
// - |Close| is similar to |Unbind| except that it causes an epitaph message to be sent on the
//   |channel|.
// - If specified, the |on_unbound| hook will execute after the epitaph has been sent and like in
//   |Unbind| the |channel| will be given as an argument to the hook and if unused it will be closed
//   at the end of the hook scope.
//
// Error conditions:
// - When an error occurs in the server implementation as part of handling a message, it may call
//   |Close| on the completer to indicate the error condition.
// - If the client end of the channel gets closed (PEER_CLOSED).
// - If an error occurs in the binding itself, e.g. a channel write fails.
//
// Ordering:
// - By default, the message dispatch function for a binding will only ever be invoked by a single
//   |dispatcher| thread at a time.
// - To enable more concurrency, the user may invoke |EnableNextDispatch| on the
//   |fidl::Completer<T>::Sync| from the dispatch function. This will resume the async wait on the
//   |dispatcher| before the dispatch function returns, allowing other |dispatcher| threads to
//   handle messages for the same binding.
// NOTE: If a particular user does not care about ordering, they may invoke |EnableNextDispatch|
// immediately in the message handler. However, this functionality could instead be provided as a
// default configuration. If you have such a usecase, please contact madhaviyengar@ or yifeit@.
//
// The following |BindServer()| APIs infer the protocol type based on the server implementation
// which must publicly inherit from the appropriate |<Protocol_Name>::Interface| class.
template <typename ServerImpl>
fit::result<ServerBindingRef<typename ServerImpl::_EnclosingProtocol>, zx_status_t> BindServer(
    async_dispatcher_t* dispatcher, zx::channel channel, ServerImpl* impl) {
  return internal::BindServerImpl<typename ServerImpl::_EnclosingProtocol>(
      dispatcher, std::move(channel), impl, nullptr);
}

// As above, but will invoke |on_unbound| on |impl| when the channel is being unbound, either due to
// error or an explicit |Close| or |Unbind|.
//
// NOTE: |on_unbound| will generally be executed from a |dispatcher| thread. However, on
// |dispatcher| shutdown, any active bindings will be unbound, thus it may also be executed on the
// thread invoking shutdown. The user must ensure that shutdown is never invoked while holding locks
// which |on_unbound| may also take.
template <typename ServerImpl>
fit::result<ServerBindingRef<typename ServerImpl::_EnclosingProtocol>, zx_status_t> BindServer(
    async_dispatcher_t* dispatcher, zx::channel channel, ServerImpl* impl,
    OnUnboundFn<ServerImpl> on_unbound) {
  return internal::BindServerImpl<typename ServerImpl::_EnclosingProtocol>(
      dispatcher, std::move(channel), impl,
      [fn = std::move(on_unbound)](internal::IncomingMessageDispatcher* any_interface,
                                   UnbindInfo info, zx::channel channel) mutable {
        // Note: this cast may change the value of the pointer, due to how C++
        // implements classes with virtual tables.
        auto* impl = static_cast<ServerImpl*>(any_interface);
        fn(impl, info, std::move(channel));
      });
}

// Similar to the first variant, however, the user gives the binding ownership of the server
// implementation. In order to destroy the implementation on unbind, the unique_ptr is passed to a
// hook which will be automatically invoked during unbinding.
//
// NOTE: The same restriction on |on_unbound| in the previous variant applies to ~Interface().
template <typename ServerImpl>
fit::result<ServerBindingRef<typename ServerImpl::_EnclosingProtocol>, zx_status_t> BindServer(
    async_dispatcher_t* dispatcher, zx::channel channel, std::unique_ptr<ServerImpl> impl) {
  ServerImpl* impl_raw = impl.get();
  return internal::BindServerImpl<typename ServerImpl::_EnclosingProtocol>(
      dispatcher, std::move(channel), impl_raw,
      [impl = std::move(impl)](internal::IncomingMessageDispatcher* interface, UnbindInfo info,
                               zx::channel channel) {});
}

namespace internal {

// Binds an implementation of some FIDL server protocol |interface| to |channel|.
//
// |interface| should be a pointer to some |FidlProtocol::Interface| class.
//
// |dispatch_fn| looks up an incoming FIDL message in the associated protocol
// and possibly invokes a handler on |interface|, which will be provided as
// the first argument.
//
// |on_unbound| will be called with |interface| if |on_unbound| is specified.
// The public |fidl::BindServer| functions should translate |interface| back to
// the user pointer type, possibly at an offset, before invoking the
// user-provided on-unbound handler.
template <typename Protocol>
fit::result<ServerBindingRef<Protocol>, zx_status_t> BindServerImpl(
    async_dispatcher_t* dispatcher, zx::channel channel, IncomingMessageDispatcher* interface,
    internal::AnyOnUnboundFn on_unbound) {
  auto internal_binding = internal::AsyncServerBinding<Protocol>::Create(
      dispatcher, std::move(channel), interface, std::move(on_unbound));
  auto status = internal_binding->BeginWait();
  if (status == ZX_OK) {
    return fit::ok(fidl::ServerBindingRef<Protocol>(std::move(internal_binding)));
  } else {
    return fit::error(status);
  }
}

}  // namespace internal

}  // namespace fidl

#endif  // LIB_FIDL_LLCPP_SERVER_H_
