// 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 "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/ppapi_globals.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_t class_int =
      static_cast<int64_t>(reinterpret_cast<intptr_t>(ppp_class));
  int64_t 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_t class_int =
      static_cast<int64_t>(reinterpret_cast<intptr_t>(ppp_class));
  int64_t data_int =
      static_cast<int64_t>(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_(nullptr) {
  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_FLASH))
    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_t object_id) {
  PP_Var var = { PP_VARTYPE_OBJECT };
  var.value.as_id = object_id;
  ppb_var_impl_->AddRef(var);
}

void PPB_Var_Deprecated_Proxy::OnMsgReleaseObject(int64_t 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.
  PpapiGlobals::Get()->GetMainThreadMessageLoop()->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_t ppp_class,
    int64_t* 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_t ppp_class,
    int64_t 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_t object_id) {
  PP_Var var = { PP_VARTYPE_OBJECT };
  var.value.as_id = object_id;
  ppb_var_impl_->Release(var);
}

}  // namespace proxy
}  // namespace ppapi
