// 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) { encoder->EncodeHandle(&channel_, 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_
