// 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_LIB_INTERFACE_PTR_INTERNAL_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_

#include <algorithm>  // For |std::swap()|.

#include "mojo/public/cpp/bindings/interface_ptr_info.h"
#include "mojo/public/cpp/bindings/lib/control_message_proxy.h"
#include "mojo/public/cpp/bindings/lib/filter_chain.h"
#include "mojo/public/cpp/bindings/lib/message_header_validator.h"
#include "mojo/public/cpp/bindings/lib/router.h"
#include "mojo/public/cpp/environment/logging.h"

struct MojoAsyncWaiter;

namespace mojo {
namespace internal {

template <typename Interface>
class InterfacePtrState {
 public:
  InterfacePtrState()
      : proxy_(nullptr), router_(nullptr), waiter_(nullptr), version_(0u) {}

  ~InterfacePtrState() {
    // Destruction order matters here. We delete |proxy_| first, even though
    // |router_| may have a reference to it, so that destructors for any request
    // callbacks still pending can interact with the InterfacePtr.
    delete proxy_;
    delete router_;
  }

  Interface* instance() {
    ConfigureProxyIfNecessary();

    // This will be null if the object is not bound.
    return proxy_;
  }

  uint32_t version() const { return version_; }

  void QueryVersion(const Callback<void(uint32_t)>& callback) {
    ConfigureProxyIfNecessary();

    // It is safe to capture |this| because the callback won't be run after this
    // object goes away.
    auto callback_wrapper = [this, callback](uint32_t version) {
      this->version_ = version;
      callback.Run(version);
    };

    // Do a static cast in case the interface contains methods with the same
    // name.
    static_cast<ControlMessageProxy*>(proxy_)->QueryVersion(callback_wrapper);
  }

  void RequireVersion(uint32_t version) {
    ConfigureProxyIfNecessary();

    if (version <= version_)
      return;

    version_ = version;
    // Do a static cast in case the interface contains methods with the same
    // name.
    static_cast<ControlMessageProxy*>(proxy_)->RequireVersion(version);
  }

  void Swap(InterfacePtrState* other) {
    using std::swap;
    swap(other->proxy_, proxy_);
    swap(other->router_, router_);
    handle_.swap(other->handle_);
    swap(other->waiter_, waiter_);
    swap(other->version_, version_);
  }

  void Bind(InterfacePtrInfo<Interface> info, const MojoAsyncWaiter* waiter) {
    MOJO_DCHECK(!proxy_);
    MOJO_DCHECK(!router_);
    MOJO_DCHECK(!handle_.is_valid());
    MOJO_DCHECK(!waiter_);
    MOJO_DCHECK(version_ == 0u);
    MOJO_DCHECK(info.is_valid());

    handle_ = info.PassHandle();
    waiter_ = waiter;
    version_ = info.version();
  }

  bool WaitForIncomingResponse() {
    ConfigureProxyIfNecessary();

    MOJO_DCHECK(router_);
    return router_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE);
  }

  // After this method is called, the object is in an invalid state and
  // shouldn't be reused.
  InterfacePtrInfo<Interface> PassInterface() {
    return InterfacePtrInfo<Interface>(
        router_ ? router_->PassMessagePipe() : handle_.Pass(), version_);
  }

  bool is_bound() const { return handle_.is_valid() || router_; }

  bool encountered_error() const {
    return router_ ? router_->encountered_error() : false;
  }

  void set_error_handler(ErrorHandler* error_handler) {
    ConfigureProxyIfNecessary();

    MOJO_DCHECK(router_);
    router_->set_error_handler(error_handler);
  }

  Router* router_for_testing() {
    ConfigureProxyIfNecessary();
    return router_;
  }

 private:
  using Proxy = typename Interface::Proxy_;

  void ConfigureProxyIfNecessary() {
    // The proxy has been configured.
    if (proxy_) {
      MOJO_DCHECK(router_);
      return;
    }
    // The object hasn't been bound.
    if (!waiter_) {
      MOJO_DCHECK(!handle_.is_valid());
      return;
    }

    FilterChain filters;
    filters.Append<MessageHeaderValidator>();
    filters.Append<typename Interface::ResponseValidator_>();

    router_ = new Router(handle_.Pass(), filters.Pass(), waiter_);
    waiter_ = nullptr;

    proxy_ = new Proxy(router_);
  }

  Proxy* proxy_;
  Router* router_;

  // |proxy_| and |router_| are not initialized until read/write with the
  // message pipe handle is needed. |handle_| and |waiter_| are valid between
  // the Bind() call and the initialization of |proxy_| and |router_|.
  ScopedMessagePipeHandle handle_;
  const MojoAsyncWaiter* waiter_;

  uint32_t version_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
};

}  // namespace internal
}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
