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

#include "ppapi/proxy/ppb_var_deprecated_proxy.h"

#include <stdlib.h>  // For malloc

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_var.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/proxy/plugin_var_tracker.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppp_class_proxy.h"
#include "ppapi/proxy/proxy_object_var.h"
#include "ppapi/proxy/serialized_var.h"
#include "ppapi/shared_impl/ppb_var_shared.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/var.h"

namespace ppapi {
namespace proxy {

namespace {

// Used to do get the set-up information for calling a var object. If the
// exception is set, returns NULL. Otherwise, computes the dispatcher for the
// given var object. If the var is not a valid object, returns NULL and sets
// the exception.
PluginDispatcher* CheckExceptionAndGetDispatcher(const PP_Var& object,
                                                 PP_Var* exception) {
  // If an exception is already set, we don't need to do anything, just return
  // an error to the caller.
  if (exception && exception->type != PP_VARTYPE_UNDEFINED)
    return NULL;


  if (object.type == PP_VARTYPE_OBJECT) {
    // Get the dispatcher for the object.
    PluginDispatcher* dispatcher =
        PluginGlobals::Get()->plugin_var_tracker()->
            DispatcherForPluginObject(object);
    if (dispatcher)
      return dispatcher;
  }

  // The object is invalid. This means we can't figure out which dispatcher
  // to use, which is OK because the call will fail anyway. Set the exception.
  if (exception) {
    *exception = StringVar::StringToPPVar(
        std::string("Attempting to use an invalid object"));
  }
  return NULL;
}

// PPB_Var_Deprecated plugin ---------------------------------------------------

bool HasProperty(PP_Var var,
                 PP_Var name,
                 PP_Var* exception) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception);
  if (!dispatcher)
    return false;

  ReceiveSerializedException se(dispatcher, exception);
  PP_Bool result = PP_FALSE;
  if (!se.IsThrown()) {
    dispatcher->Send(new PpapiHostMsg_PPBVar_HasProperty(
        API_ID_PPB_VAR_DEPRECATED,
        SerializedVarSendInput(dispatcher, var),
        SerializedVarSendInput(dispatcher, name), &se, &result));
  }
  return PP_ToBool(result);
}

bool HasMethod(PP_Var var,
               PP_Var name,
               PP_Var* exception) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception);
  if (!dispatcher)
    return false;

  ReceiveSerializedException se(dispatcher, exception);
  PP_Bool result = PP_FALSE;
  if (!se.IsThrown()) {
    dispatcher->Send(new PpapiHostMsg_PPBVar_HasMethodDeprecated(
        API_ID_PPB_VAR_DEPRECATED,
        SerializedVarSendInput(dispatcher, var),
        SerializedVarSendInput(dispatcher, name), &se, &result));
  }
  return PP_ToBool(result);
}

PP_Var GetProperty(PP_Var var,
                   PP_Var name,
                   PP_Var* exception) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception);
  if (!dispatcher)
    return PP_MakeUndefined();

  ReceiveSerializedException se(dispatcher, exception);
  ReceiveSerializedVarReturnValue result;
  if (!se.IsThrown()) {
    dispatcher->Send(new PpapiHostMsg_PPBVar_GetProperty(
        API_ID_PPB_VAR_DEPRECATED,
        SerializedVarSendInput(dispatcher, var),
        SerializedVarSendInput(dispatcher, name), &se, &result));
  }
  return result.Return(dispatcher);
}

void EnumerateProperties(PP_Var var,
                         uint32_t* property_count,
                         PP_Var** properties,
                         PP_Var* exception) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception);
  if (!dispatcher) {
    *property_count = 0;
    *properties = NULL;
    return;
  }

  ReceiveSerializedVarVectorOutParam out_vector(dispatcher,
                                                property_count, properties);
  ReceiveSerializedException se(dispatcher, exception);
  if (!se.IsThrown()) {
    dispatcher->Send(new PpapiHostMsg_PPBVar_EnumerateProperties(
        API_ID_PPB_VAR_DEPRECATED,
        SerializedVarSendInput(dispatcher, var),
        out_vector.OutParam(), &se));
  }
}

void SetProperty(PP_Var var,
                 PP_Var name,
                 PP_Var value,
                 PP_Var* exception) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception);
  if (!dispatcher)
    return;

  ReceiveSerializedException se(dispatcher, exception);
  if (!se.IsThrown()) {
    dispatcher->Send(new PpapiHostMsg_PPBVar_SetPropertyDeprecated(
        API_ID_PPB_VAR_DEPRECATED,
        SerializedVarSendInput(dispatcher, var),
        SerializedVarSendInput(dispatcher, name),
        SerializedVarSendInput(dispatcher, value), &se));
  }
}

void RemoveProperty(PP_Var var,
                    PP_Var name,
                    PP_Var* exception) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception);
  if (!dispatcher)
    return;

  ReceiveSerializedException se(dispatcher, exception);
  PP_Bool result = PP_FALSE;
  if (!se.IsThrown()) {
    dispatcher->Send(new PpapiHostMsg_PPBVar_DeleteProperty(
        API_ID_PPB_VAR_DEPRECATED,
        SerializedVarSendInput(dispatcher, var),
        SerializedVarSendInput(dispatcher, name), &se, &result));
  }
}

PP_Var Call(PP_Var object,
            PP_Var method_name,
            uint32_t argc,
            PP_Var* argv,
            PP_Var* exception) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(object, exception);
  if (!dispatcher)
    return PP_MakeUndefined();

  ReceiveSerializedVarReturnValue result;
  ReceiveSerializedException se(dispatcher, exception);
  if (!se.IsThrown()) {
    std::vector<SerializedVar> argv_vect;
    SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect);

    dispatcher->Send(new PpapiHostMsg_PPBVar_CallDeprecated(
        API_ID_PPB_VAR_DEPRECATED,
        SerializedVarSendInput(dispatcher, object),
        SerializedVarSendInput(dispatcher, method_name), argv_vect,
        &se, &result));
  }
  return result.Return(dispatcher);
}

PP_Var Construct(PP_Var object,
                 uint32_t argc,
                 PP_Var* argv,
                 PP_Var* exception) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(object, exception);
  if (!dispatcher)
    return PP_MakeUndefined();

  ReceiveSerializedVarReturnValue result;
  ReceiveSerializedException se(dispatcher, exception);
  if (!se.IsThrown()) {
    std::vector<SerializedVar> argv_vect;
    SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect);

    dispatcher->Send(new PpapiHostMsg_PPBVar_Construct(
        API_ID_PPB_VAR_DEPRECATED,
        SerializedVarSendInput(dispatcher, object),
        argv_vect, &se, &result));
  }
  return result.Return(dispatcher);
}

bool IsInstanceOf(PP_Var var,
                  const PPP_Class_Deprecated* ppp_class,
                  void** ppp_class_data) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, NULL);
  if (!dispatcher)
    return false;

  PP_Bool result = PP_FALSE;
  int64 class_int = static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class));
  int64 class_data_int = 0;
  dispatcher->Send(new PpapiHostMsg_PPBVar_IsInstanceOfDeprecated(
      API_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var),
      class_int, &class_data_int, &result));
  *ppp_class_data =
      reinterpret_cast<void*>(static_cast<intptr_t>(class_data_int));
  return PP_ToBool(result);
}

PP_Var CreateObject(PP_Instance instance,
                    const PPP_Class_Deprecated* ppp_class,
                    void* ppp_class_data) {
  ProxyAutoLock lock;
  Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
  if (!dispatcher)
    return PP_MakeUndefined();

  PluginVarTracker* tracker = PluginGlobals::Get()->plugin_var_tracker();
  if (tracker->IsPluginImplementedObjectAlive(ppp_class_data))
    return PP_MakeUndefined();  // Object already exists with this user data.

  ReceiveSerializedVarReturnValue result;
  int64 class_int = static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class));
  int64 data_int =
      static_cast<int64>(reinterpret_cast<intptr_t>(ppp_class_data));
  dispatcher->Send(new PpapiHostMsg_PPBVar_CreateObjectDeprecated(
      API_ID_PPB_VAR_DEPRECATED, instance, class_int, data_int,
      &result));
  PP_Var ret_var = result.Return(dispatcher);

  // Register this object as being implemented by the plugin.
  if (ret_var.type == PP_VARTYPE_OBJECT) {
    tracker->PluginImplementedObjectCreated(instance, ret_var,
                                            ppp_class, ppp_class_data);
  }
  return ret_var;
}

}  // namespace

PPB_Var_Deprecated_Proxy::PPB_Var_Deprecated_Proxy(
    Dispatcher* dispatcher)
    : InterfaceProxy(dispatcher),
      ppb_var_impl_(NULL),
      task_factory_(this) {
  if (!dispatcher->IsPlugin()) {
    ppb_var_impl_ = static_cast<const PPB_Var_Deprecated*>(
        dispatcher->local_get_interface()(PPB_VAR_DEPRECATED_INTERFACE));
  }
}

PPB_Var_Deprecated_Proxy::~PPB_Var_Deprecated_Proxy() {
}

// static
const PPB_Var_Deprecated* PPB_Var_Deprecated_Proxy::GetProxyInterface() {
  static const PPB_Var_Deprecated var_deprecated_interface = {
    ppapi::PPB_Var_Shared::GetVarInterface1_0()->AddRef,
    ppapi::PPB_Var_Shared::GetVarInterface1_0()->Release,
    ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8,
    ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8,
    &HasProperty,
    &HasMethod,
    &GetProperty,
    &EnumerateProperties,
    &SetProperty,
    &RemoveProperty,
    &Call,
    &Construct,
    &IsInstanceOf,
    &CreateObject
  };
  return &var_deprecated_interface;
}

bool PPB_Var_Deprecated_Proxy::OnMessageReceived(const IPC::Message& msg) {
  if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
    return false;

  // Prevent the dispatcher from going away during a call to Call or other
  // function that could mutate the DOM. This must happen OUTSIDE of
  // the message handlers since the SerializedVars use the dispatcher upon
  // return of the function (converting the SerializedVarReturnValue/OutParam
  // to a SerializedVar in the destructor).
  ScopedModuleReference death_grip(dispatcher());

  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(PPB_Var_Deprecated_Proxy, msg)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_AddRefObject, OnMsgAddRefObject)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_ReleaseObject, OnMsgReleaseObject)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasProperty,
                        OnMsgHasProperty)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasMethodDeprecated,
                        OnMsgHasMethodDeprecated)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_GetProperty,
                        OnMsgGetProperty)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_DeleteProperty,
                        OnMsgDeleteProperty)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_EnumerateProperties,
                        OnMsgEnumerateProperties)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_SetPropertyDeprecated,
                        OnMsgSetPropertyDeprecated)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CallDeprecated,
                        OnMsgCallDeprecated)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_Construct,
                        OnMsgConstruct)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_IsInstanceOfDeprecated,
                        OnMsgIsInstanceOfDeprecated)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CreateObjectDeprecated,
                        OnMsgCreateObjectDeprecated)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  // TODO(brettw) handle bad messages!
  return handled;
}

void PPB_Var_Deprecated_Proxy::OnMsgAddRefObject(int64 object_id,
                                                 int* /* unused */) {
  PP_Var var = { PP_VARTYPE_OBJECT };
  var.value.as_id = object_id;
  ppb_var_impl_->AddRef(var);
}

void PPB_Var_Deprecated_Proxy::OnMsgReleaseObject(int64 object_id) {
  // Ok, so this is super subtle.
  // When the browser side sends a sync IPC message that returns a var, and the
  // plugin wants to give ownership of that var to the browser, dropping all
  // references, it may call ReleaseObject right after returning the result.
  // However, the IPC system doesn't enforce strict ordering of messages in that
  // case, where a message that is set to unblock (e.g. a sync message, or in
  // our case all messages coming from the plugin) that is sent *after* the
  // result may be dispatched on the browser side *before* the sync send
  // returned (see ipc_sync_channel.cc). In this case, that means it could
  // release the object before it is AddRef'ed on the browser side.
  // To work around this, we post a task here, that will not execute before
  // control goes back to the main message loop, that will ensure the sync send
  // has returned and the browser side can take its reference before we Release.
  // Note: if the instance is gone by the time the task is executed, then it
  // will Release the objects itself and this Release will be a NOOP (aside of a
  // spurious warning).
  // TODO(piman): See if we can fix the IPC code to enforce strict ordering, and
  // then remove this.
  base::MessageLoop::current()->PostNonNestableTask(
      FROM_HERE,
      RunWhileLocked(base::Bind(&PPB_Var_Deprecated_Proxy::DoReleaseObject,
                                task_factory_.GetWeakPtr(),
                                object_id)));
}

void PPB_Var_Deprecated_Proxy::OnMsgHasProperty(
    SerializedVarReceiveInput var,
    SerializedVarReceiveInput name,
    SerializedVarOutParam exception,
    PP_Bool* result) {
  SetAllowPluginReentrancy();
  *result = PP_FromBool(ppb_var_impl_->HasProperty(
      var.Get(dispatcher()),
      name.Get(dispatcher()),
      exception.OutParam(dispatcher())));
}

void PPB_Var_Deprecated_Proxy::OnMsgHasMethodDeprecated(
    SerializedVarReceiveInput var,
    SerializedVarReceiveInput name,
    SerializedVarOutParam exception,
    PP_Bool* result) {
  SetAllowPluginReentrancy();
  *result = PP_FromBool(ppb_var_impl_->HasMethod(
      var.Get(dispatcher()),
      name.Get(dispatcher()),
      exception.OutParam(dispatcher())));
}

void PPB_Var_Deprecated_Proxy::OnMsgGetProperty(
    SerializedVarReceiveInput var,
    SerializedVarReceiveInput name,
    SerializedVarOutParam exception,
    SerializedVarReturnValue result) {
  SetAllowPluginReentrancy();
  result.Return(dispatcher(), ppb_var_impl_->GetProperty(
      var.Get(dispatcher()), name.Get(dispatcher()),
      exception.OutParam(dispatcher())));
}

void PPB_Var_Deprecated_Proxy::OnMsgEnumerateProperties(
    SerializedVarReceiveInput var,
    SerializedVarVectorOutParam props,
    SerializedVarOutParam exception) {
  SetAllowPluginReentrancy();
  ppb_var_impl_->GetAllPropertyNames(var.Get(dispatcher()),
      props.CountOutParam(), props.ArrayOutParam(dispatcher()),
      exception.OutParam(dispatcher()));
}

void PPB_Var_Deprecated_Proxy::OnMsgSetPropertyDeprecated(
    SerializedVarReceiveInput var,
    SerializedVarReceiveInput name,
    SerializedVarReceiveInput value,
    SerializedVarOutParam exception) {
  SetAllowPluginReentrancy();
  ppb_var_impl_->SetProperty(var.Get(dispatcher()),
                                name.Get(dispatcher()),
                                value.Get(dispatcher()),
                                exception.OutParam(dispatcher()));
}

void PPB_Var_Deprecated_Proxy::OnMsgDeleteProperty(
    SerializedVarReceiveInput var,
    SerializedVarReceiveInput name,
    SerializedVarOutParam exception,
    PP_Bool* result) {
  SetAllowPluginReentrancy();
  ppb_var_impl_->RemoveProperty(var.Get(dispatcher()),
                                   name.Get(dispatcher()),
                                   exception.OutParam(dispatcher()));
  // This deprecated function doesn't actually return a value, but we re-use
  // the message from the non-deprecated interface with the return value.
  *result = PP_TRUE;
}

void PPB_Var_Deprecated_Proxy::OnMsgCallDeprecated(
    SerializedVarReceiveInput object,
    SerializedVarReceiveInput method_name,
    SerializedVarVectorReceiveInput arg_vector,
    SerializedVarOutParam exception,
    SerializedVarReturnValue result) {
  SetAllowPluginReentrancy();
  uint32_t arg_count = 0;
  PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
  result.Return(dispatcher(), ppb_var_impl_->Call(
      object.Get(dispatcher()),
      method_name.Get(dispatcher()),
      arg_count, args,
      exception.OutParam(dispatcher())));
}

void PPB_Var_Deprecated_Proxy::OnMsgConstruct(
    SerializedVarReceiveInput var,
    SerializedVarVectorReceiveInput arg_vector,
    SerializedVarOutParam exception,
    SerializedVarReturnValue result) {
  SetAllowPluginReentrancy();
  uint32_t arg_count = 0;
  PP_Var* args = arg_vector.Get(dispatcher(), &arg_count);
  result.Return(dispatcher(), ppb_var_impl_->Construct(
      var.Get(dispatcher()), arg_count, args,
      exception.OutParam(dispatcher())));
}

void PPB_Var_Deprecated_Proxy::OnMsgIsInstanceOfDeprecated(
    SerializedVarReceiveInput var,
    int64 ppp_class,
    int64* ppp_class_data,
    PP_Bool* result) {
  SetAllowPluginReentrancy();
  *result = PPP_Class_Proxy::IsInstanceOf(ppb_var_impl_,
                                          var.Get(dispatcher()),
                                          ppp_class,
                                          ppp_class_data);
}

void PPB_Var_Deprecated_Proxy::OnMsgCreateObjectDeprecated(
    PP_Instance instance,
    int64 ppp_class,
    int64 class_data,
    SerializedVarReturnValue result) {
  SetAllowPluginReentrancy();
  result.Return(dispatcher(), PPP_Class_Proxy::CreateProxiedObject(
      ppb_var_impl_, dispatcher(), instance, ppp_class, class_data));
}

void PPB_Var_Deprecated_Proxy::SetAllowPluginReentrancy() {
  if (dispatcher()->IsPlugin())
    NOTREACHED();
  else
    static_cast<HostDispatcher*>(dispatcher())->set_allow_plugin_reentrancy();
}

void PPB_Var_Deprecated_Proxy::DoReleaseObject(int64 object_id) {
  PP_Var var = { PP_VARTYPE_OBJECT };
  var.value.as_id = object_id;
  ppb_var_impl_->Release(var);
}

}  // namespace proxy
}  // namespace ppapi
