// Copyright (c) 2012 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 PPAPI_PROXY_ENTER_PROXY_H_
#define PPAPI_PROXY_ENTER_PROXY_H_

#include <stdint.h>

#include "base/logging.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/thunk/enter.h"

namespace ppapi {

namespace proxy {

// Wrapper around EnterResourceNoLock that takes a host resource. This is used
// when handling messages in the plugin from the host and we need to convert to
// an object in the plugin side corresponding to that.
//
// This never locks since we assume the host Resource is coming from IPC, and
// never logs errors since we assume the host is doing reasonable things.
template<typename ResourceT>
class EnterPluginFromHostResource
    : public thunk::EnterResourceNoLock<ResourceT> {
 public:
  explicit EnterPluginFromHostResource(const HostResource& host_resource)
      : thunk::EnterResourceNoLock<ResourceT>(
            PluginGlobals::Get()->plugin_resource_tracker()->
                PluginResourceForHostResource(host_resource),
            false) {
    // Validate that we're in the plugin rather than the host. Otherwise this
    // object will do the wrong thing. In the plugin, the instance should have
    // a corresponding plugin dispatcher (assuming the resource is valid).
    DCHECK(this->failed() ||
           PluginDispatcher::GetForInstance(host_resource.instance()));
  }
};

template<typename ResourceT>
class EnterHostFromHostResource
    : public thunk::EnterResourceNoLock<ResourceT> {
 public:
  explicit EnterHostFromHostResource(const HostResource& host_resource)
      : thunk::EnterResourceNoLock<ResourceT>(host_resource.host_resource(),
                                              false) {
    // Validate that we're in the host rather than the plugin. Otherwise this
    // object will do the wrong thing. In the host, the instance should have
    // a corresponding host disptacher (assuming the resource is valid).
    DCHECK(this->failed() ||
           HostDispatcher::GetForInstance(host_resource.instance()));
  }

  EnterHostFromHostResource(const HostResource& host_resource,
                            const pp::CompletionCallback& callback)
      : thunk::EnterResourceNoLock<ResourceT>(host_resource.host_resource(),
                                              callback.pp_completion_callback(),
                                              false) {
    // Validate that we're in the host rather than the plugin. Otherwise this
    // object will do the wrong thing. In the host, the instance should have
    // a corresponding host disptacher (assuming the resource is valid).
    DCHECK(this->failed() ||
           HostDispatcher::GetForInstance(host_resource.instance()));
  }
};

// Enters a resource and forces a completion callback to be issued.
//
// This is used when implementing the host (renderer) side of a resource
// function that issues a completion callback. In all cases, we need to issue
// the callback to avoid hanging the plugin.
//
// This class automatically constructs a callback with the given factory
// calling the given method. The method will generally be the one that sends
// the message to trigger the completion callback in the plugin process.
//
// It will automatically issue the callback with PP_ERROR_NOINTERFACE if the
// host resource is invalid (i.e. failed() is set). In all other cases you
// should call SetResult(), which will issue the callback immediately if the
// result value isn't PP_OK_COMPLETIONPENDING. In the "completion pending"
// case, it's assumed the function the proxy is calling will take responsibility
// of executing the callback (returned by callback()).
//
// Example:
//   EnterHostFromHostResourceForceCallback<PPB_Foo_API> enter(
//       resource, callback_factory_, &MyClass::SendResult, resource);
//   if (enter.failed())
//     return;  // SendResult automatically called with PP_ERROR_BADRESOURCE.
//   enter.SetResult(enter.object()->DoFoo(enter.callback()));
//
// Where DoFoo's signature looks like this:
//   int32_t DoFoo(PP_CompletionCallback callback);
// And SendResult's implementation looks like this:
//   void MyClass::SendResult(int32_t result, const HostResource& res) {
//     Send(new FooMsg_FooComplete(..., result, res));
//   }
template<typename ResourceT>
class EnterHostFromHostResourceForceCallback
    : public EnterHostFromHostResource<ResourceT> {
 public:
  EnterHostFromHostResourceForceCallback(
      const HostResource& host_resource,
      const pp::CompletionCallback& callback)
      : EnterHostFromHostResource<ResourceT>(host_resource, callback),
        needs_running_(true) {
  }

  // For callbacks that take no parameters except the "int32_t result". Most
  // implementations will use the 1-extra-argument constructor below.
  template<class CallbackFactory, typename Method>
  EnterHostFromHostResourceForceCallback(
      const HostResource& host_resource,
      CallbackFactory& factory,
      Method method)
      : EnterHostFromHostResource<ResourceT>(host_resource,
            factory.NewOptionalCallback(method)),
        needs_running_(true) {
    if (this->failed())
      RunCallback(PP_ERROR_BADRESOURCE);
  }

  // For callbacks that take an extra parameter as a closure.
  template<class CallbackFactory, typename Method, typename A>
  EnterHostFromHostResourceForceCallback(
      const HostResource& host_resource,
      CallbackFactory& factory,
      Method method,
      const A& a)
      : EnterHostFromHostResource<ResourceT>(host_resource,
            factory.NewOptionalCallback(method, a)),
        needs_running_(true) {
    if (this->failed())
      RunCallback(PP_ERROR_BADRESOURCE);
  }

  // For callbacks that take two extra parameters as a closure.
  template<class CallbackFactory, typename Method, typename A, typename B>
  EnterHostFromHostResourceForceCallback(
      const HostResource& host_resource,
      CallbackFactory& factory,
      Method method,
      const A& a,
      const B& b)
      : EnterHostFromHostResource<ResourceT>(host_resource,
            factory.NewOptionalCallback(method, a, b)),
        needs_running_(true) {
    if (this->failed())
      RunCallback(PP_ERROR_BADRESOURCE);
  }

  // For callbacks that take three extra parameters as a closure.
  template<class CallbackFactory, typename Method, typename A, typename B,
           typename C>
  EnterHostFromHostResourceForceCallback(
      const HostResource& host_resource,
      CallbackFactory& factory,
      Method method,
      const A& a,
      const B& b,
      const C& c)
      : EnterHostFromHostResource<ResourceT>(host_resource,
            factory.NewOptionalCallback(method, a, b, c)),
        needs_running_(true) {
    if (this->failed())
      RunCallback(PP_ERROR_BADRESOURCE);
  }

  ~EnterHostFromHostResourceForceCallback() {
    if (needs_running_) {
      NOTREACHED() << "Should always call SetResult except in the "
                      "initialization failed case.";
      RunCallback(PP_ERROR_FAILED);
    }
  }

  void SetResult(int32_t result) {
    DCHECK(needs_running_) << "Don't call SetResult when there already is one.";
    if (result != PP_OK_COMPLETIONPENDING)
      RunCallback(result);
    needs_running_ = false;
    // Either we already ran the callback, or it will be run asynchronously. We
    // clear the callback so it isn't accidentally run again (and because
    // EnterBase checks that the callback has been cleared).
    this->ClearCallback();
  }

 private:
  void RunCallback(int32_t result) {
    DCHECK(needs_running_);
    needs_running_ = false;
    this->callback()->Run(result);
    this->ClearCallback();
  }

  bool needs_running_;
};

}  // namespace proxy
}  // namespace ppapi

#endif  // PPAPI_PROXY_ENTER_PROXY_H_
