// 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 <assert.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"

struct MojoAsyncWaiter;

namespace mojo {
namespace internal {

template <typename Interface>
class InterfacePtrState {
 public:
  InterfacePtrState() : proxy_(NULL), router_(NULL), waiter_(NULL) {}

  ~InterfacePtrState() {
    // Destruction order matters here. We delete |proxy_| first, even though
    // |router_| may have a reference to it, so that |~Interface| may have a
    // shot at generating new outbound messages (ie, invoking client methods).
    delete proxy_;
    delete router_;
  }

  Interface* instance() {
    ConfigureProxyIfNecessary();

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

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

  void Bind(ScopedMessagePipeHandle handle, const MojoAsyncWaiter* waiter) {
    assert(!proxy_);
    assert(!router_);
    assert(!handle_.is_valid());
    assert(!waiter_);

    handle_ = handle.Pass();
    waiter_ = waiter;
  }

  bool WaitForIncomingMethodCall() {
    ConfigureProxyIfNecessary();

    assert(router_);
    return router_->WaitForIncomingMessage();
  }

  ScopedMessagePipeHandle PassMessagePipe() {
    if (router_)
      return router_->PassMessagePipe();

    waiter_ = NULL;
    return handle_.Pass();
  }

  void set_client(typename Interface::Client* client) {
    ConfigureProxyIfNecessary();

    assert(proxy_);
    proxy_->stub.set_sink(client);
  }

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

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

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

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

 private:
  class ProxyWithStub : public Interface::Proxy_ {
   public:
    explicit ProxyWithStub(MessageReceiverWithResponder* receiver)
        : Interface::Proxy_(receiver) {
    }
    typename Interface::Client::Stub_ stub;
   private:
    MOJO_DISALLOW_COPY_AND_ASSIGN(ProxyWithStub);
  };

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

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

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

    ProxyWithStub* proxy = new ProxyWithStub(router_);
    router_->set_incoming_receiver(&proxy->stub);

    proxy_ = proxy;
  }

  ProxyWithStub* proxy_;
  Router* router_;

  // |proxy_| and |router_| are not initialized until read/write with the
  // message pipe handle is needed. Before that, |handle_| and |waiter_| store
  // the arguments of Bind().
  ScopedMessagePipeHandle handle_;
  const MojoAsyncWaiter* waiter_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(InterfacePtrState);
};

}  // namespace internal
}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_INTERFACE_PTR_INTERNAL_H_
