// 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_INTERFACE_REQUEST_H_
#define LIB_FIDL_CPP_INTERFACE_REQUEST_H_

#include <lib/fidl/epitaph.h>
#include <lib/fit/function.h>
#include <lib/zx/channel.h>

#include <cstddef>
#include <utility>

#include "lib/fidl/cpp/clone.h"
#include "lib/fidl/cpp/coding_traits.h"

namespace fidl {
class Builder;

// The server endpoint of a FIDL channel.
//
// The remote end of the channel expects this end of the channel to speak the
// protocol associated with |Interface|. This type is the dual of
// |InterfaceHandle|.
//
// An |InterfaceRequest| does not have thread affinity and can therefore be
// transferred to another thread or another process. To bind an implementation
// of |Interface| to this |InterfaceRequest|, use a |Binding| object.
//
// Typically, |InterfaceRequest| objects are created by a prospective client of
// |Interface|, which then sends the |InterfaceRequest| to another process to
// request that the remote process implement the |Interface|. This pattern
// enables *pipelined* operation, in which the client can start calling methods
// on an associated |InterfacePtr| immediately, before the |InterfaceRequest|
// has reached the remote process and been bound to an implementation. These
// method calls are buffered by the underlying channel until they are read by
// the remote process.
//
// 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 |InterfaceRequest| has been bound to an implementation, the
// implementation will receive method calls from the remote endpoint of the
// channel on the thread to which the |InterfaceRequest| was bound.
//
// See also:
//
//  * |InterfaceHandle|, which is the client analog of an |InterfaceRequest|.
template <typename Interface>
class InterfaceRequest final {
 public:
  // Creates an |InterfaceHandle| whose underlying channel is invalid.
  //
  // Some protocols contain messages that permit such |InterfaceRequest|
  // objects, which indicate that the client is not interested in the server
  // providing an implementation of |Interface|.
  InterfaceRequest() = default;

  // Creates an |InterfaceHandle| that wraps the given |channel|.
  explicit InterfaceRequest(zx::channel channel) : channel_(std::move(channel)) {}

  InterfaceRequest(const InterfaceRequest& other) = delete;
  InterfaceRequest& operator=(const InterfaceRequest& other) = delete;

  InterfaceRequest(InterfaceRequest&& other) : channel_(std::move(other.channel_)) {}

  InterfaceRequest& operator=(InterfaceRequest&& other) {
    channel_ = std::move(other.channel_);
    return *this;
  }

  // Implicit conversion from nullptr to an |InterfaceRequest| with an
  // invalid |channel|.
  InterfaceRequest(std::nullptr_t) {}

  // Whether the underlying channel is valid.
  bool is_valid() const { return !!channel_; }
  explicit operator bool() const { return is_valid(); }

  // Transfers ownership of the underlying channel to the caller.
  zx::channel TakeChannel() { return std::move(channel_); }

  // The underlying channel.
  const zx::channel& channel() const { return channel_; }
  void set_channel(zx::channel channel) { channel_ = std::move(channel); }

  void Encode(Encoder* encoder, size_t offset,
              fit::optional<::fidl::HandleInformation> maybe_handle_info = fit::nullopt) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    encoder->EncodeHandle(&channel_, ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, offset);
  }

  static void Decode(Decoder* decoder, InterfaceRequest<Interface>* value, size_t offset) {
    decoder->DecodeHandle(&value->channel_, offset);
  }

  // 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 is_valid() ? fidl_epitaph_write(TakeChannel().get(), epitaph_value) : ZX_ERR_BAD_STATE;
  }

 private:
  zx::channel channel_;
};

// A |InterfaceRequestHandler<Interface>| is simply a function that
// handles an interface request for |Interface|. If it determines that the
// request should be "accepted", then it should "connect" ("take ownership
// of") request. Otherwise, it can simply drop |request| (as implied by the
// interface).
template <typename Interface>
using InterfaceRequestHandler = fit::function<void(fidl::InterfaceRequest<Interface> request)>;

// Equality.
template <typename T>
struct Equality<InterfaceRequest<T>> {
  bool operator()(const InterfaceRequest<T>& lhs, const InterfaceRequest<T>& rhs) const {
    return lhs.channel() == rhs.channel();
  }
};

template <typename T>
struct CodingTraits<InterfaceRequest<T>>
    : public EncodableCodingTraits<InterfaceRequest<T>, sizeof(zx_handle_t)> {};

template <typename T>
inline zx_status_t Clone(const InterfaceRequest<T>& value, InterfaceRequest<T>* result) {
  if (!value) {
    *result = InterfaceRequest<T>();
    return ZX_OK;
  }
  return ZX_ERR_ACCESS_DENIED;
}

}  // namespace fidl

#endif  // LIB_FIDL_CPP_INTERFACE_REQUEST_H_
