// 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/stdcompat/optional.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,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    ZX_DEBUG_ASSERT(maybe_handle_info);
    encoder->EncodeHandle(&channel_, maybe_handle_info->object_type, maybe_handle_info->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_
