// Copyright 2014 The Chromium 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 MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_
#define MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_

#include <string>
#include <utility>

#include "base/macros.h"
#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/disconnect_reason.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/pipe_control_message_proxy.h"
#include "mojo/public/cpp/system/message_pipe.h"

namespace mojo {

// Represents a request from a remote client for an implementation of Interface
// over a specified message pipe. The implementor of the interface should
// remove the message pipe by calling PassMessagePipe() and bind it to the
// implementation. If this is not done, the InterfaceRequest will automatically
// close the pipe on destruction. Can also represent the absence of a request
// if the client did not provide a message pipe.
template <typename Interface>
class InterfaceRequest {
 public:
  // Constructs an empty InterfaceRequest, representing that the client is not
  // requesting an implementation of Interface.
  InterfaceRequest() {}
  InterfaceRequest(decltype(nullptr)) {}

  explicit InterfaceRequest(ScopedMessagePipeHandle handle)
      : handle_(std::move(handle)) {}

  // Takes the message pipe from another InterfaceRequest.
  InterfaceRequest(InterfaceRequest&& other) {
    handle_ = std::move(other.handle_);
  }
  InterfaceRequest& operator=(InterfaceRequest&& other) {
    handle_ = std::move(other.handle_);
    return *this;
  }

  // Assigning to nullptr resets the InterfaceRequest to an empty state,
  // closing the message pipe currently bound to it (if any).
  InterfaceRequest& operator=(decltype(nullptr)) {
    handle_.reset();
    return *this;
  }

  // Indicates whether the request currently contains a valid message pipe.
  bool is_pending() const { return handle_.is_valid(); }

  explicit operator bool() const { return handle_.is_valid(); }

  // Removes the message pipe from the request and returns it.
  ScopedMessagePipeHandle PassMessagePipe() { return std::move(handle_); }

  bool Equals(const InterfaceRequest& other) const {
    if (this == &other)
      return true;

    // Now that the two refer to different objects, they are equivalent if
    // and only if they are both invalid.
    return !is_pending() && !other.is_pending();
  }

  void ResetWithReason(uint32_t custom_reason, const std::string& description) {
    if (!handle_.is_valid())
      return;

    Message message =
        PipeControlMessageProxy::ConstructPeerEndpointClosedMessage(
            kMasterInterfaceId, DisconnectReason(custom_reason, description));
    MojoResult result = WriteMessageNew(
        handle_.get(), message.TakeMojoMessage(), MOJO_WRITE_MESSAGE_FLAG_NONE);
    DCHECK_EQ(MOJO_RESULT_OK, result);

    handle_.reset();
  }

 private:
  ScopedMessagePipeHandle handle_;

  DISALLOW_COPY_AND_ASSIGN(InterfaceRequest);
};

// Creates a new message pipe over which Interface is to be served. Binds the
// specified InterfacePtr to one end of the message pipe, and returns an
// InterfaceRequest bound to the other. The InterfacePtr should be passed to
// the client, and the InterfaceRequest should be passed to whatever will
// provide the implementation. The implementation should typically be bound to
// the InterfaceRequest using the Binding or StrongBinding classes. The client
// may begin to issue calls even before an implementation has been bound, since
// messages sent over the pipe will just queue up until they are consumed by
// the implementation.
//
// Example #1: Requesting a remote implementation of an interface.
// ===============================================================
//
// Given the following interface:
//
//   interface Database {
//     OpenTable(Table& table);
//   }
//
// The client would have code similar to the following:
//
//   DatabasePtr database = ...;  // Connect to database.
//   TablePtr table;
//   database->OpenTable(MakeRequest(&table));
//
// Upon return from MakeRequest, |table| is ready to have methods called on it.
//
// Example #2: Registering a local implementation with a remote service.
// =====================================================================
//
// Given the following interface
//   interface Collector {
//     RegisterSource(Source source);
//   }
//
// The client would have code similar to the following:
//
//   CollectorPtr collector = ...;  // Connect to Collector.
//   SourcePtr source;
//   InterfaceRequest<Source> source_request(&source);
//   collector->RegisterSource(std::move(source));
//   CreateSource(std::move(source_request));  // Create implementation locally.
//
template <typename Interface>
InterfaceRequest<Interface> MakeRequest(
    InterfacePtr<Interface>* ptr,
    scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr) {
  MessagePipe pipe;
  ptr->Bind(InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u),
            std::move(runner));
  return InterfaceRequest<Interface>(std::move(pipe.handle1));
}

// Similar to the constructor above, but binds one end of the message pipe to
// an InterfacePtrInfo instance.
template <typename Interface>
InterfaceRequest<Interface> MakeRequest(InterfacePtrInfo<Interface>* ptr_info) {
  MessagePipe pipe;
  ptr_info->set_handle(std::move(pipe.handle0));
  ptr_info->set_version(0u);
  return InterfaceRequest<Interface>(std::move(pipe.handle1));
}

// Fuses an InterfaceRequest<T> endpoint with an InterfacePtrInfo<T> endpoint.
// Returns |true| on success or |false| on failure.
template <typename Interface>
bool FuseInterface(InterfaceRequest<Interface> request,
                   InterfacePtrInfo<Interface> proxy_info) {
  MojoResult result = FuseMessagePipes(request.PassMessagePipe(),
                                       proxy_info.PassHandle());
  return result == MOJO_RESULT_OK;
}

}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_INTERFACE_REQUEST_H_
