// 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/plugin_var_tracker.h"

#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/dev/ppp_class_deprecated.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/proxy/file_system_resource.h"
#include "ppapi/proxy/media_stream_audio_track_resource.h"
#include "ppapi/proxy/media_stream_video_track_resource.h"
#include "ppapi/proxy/plugin_array_buffer_var.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/plugin_resource_var.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/proxy_object_var.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/var.h"

namespace ppapi {
namespace proxy {

namespace {

Connection GetConnectionForInstance(PP_Instance instance) {
  PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
  DCHECK(dispatcher);
  return Connection(PluginGlobals::Get()->GetBrowserSender(), dispatcher);
}

}  // namespace

PluginVarTracker::HostVar::HostVar(PluginDispatcher* d, int32 i)
    : dispatcher(d),
      host_object_id(i) {
}

bool PluginVarTracker::HostVar::operator<(const HostVar& other) const {
  if (dispatcher < other.dispatcher)
    return true;
  if (other.dispatcher < dispatcher)
    return false;
  return host_object_id < other.host_object_id;
}

PluginVarTracker::PluginVarTracker() : VarTracker(THREAD_SAFE) {
}

PluginVarTracker::~PluginVarTracker() {
}

PP_Var PluginVarTracker::ReceiveObjectPassRef(const PP_Var& host_var,
                                              PluginDispatcher* dispatcher) {
  CheckThreadingPreconditions();
  DCHECK(host_var.type == PP_VARTYPE_OBJECT);

  // Get the object.
  scoped_refptr<ProxyObjectVar> object(
      FindOrMakePluginVarFromHostVar(host_var, dispatcher));

  // Actually create the PP_Var, this will add all the tracking info but not
  // adjust any refcounts.
  PP_Var ret = GetOrCreateObjectVarID(object.get());

  VarInfo& info = GetLiveVar(ret)->second;
  if (info.ref_count > 0) {
    // We already had a reference to it before. That means the renderer now has
    // two references on our behalf. We want to transfer that extra reference
    // to our list. This means we addref in the plugin, and release the extra
    // one in the renderer.
    SendReleaseObjectMsg(*object.get());
  }
  info.ref_count++;
  return ret;
}

PP_Var PluginVarTracker::TrackObjectWithNoReference(
    const PP_Var& host_var,
    PluginDispatcher* dispatcher) {
  CheckThreadingPreconditions();
  DCHECK(host_var.type == PP_VARTYPE_OBJECT);

  // Get the object.
  scoped_refptr<ProxyObjectVar> object(
      FindOrMakePluginVarFromHostVar(host_var, dispatcher));

  // Actually create the PP_Var, this will add all the tracking info but not
  // adjust any refcounts.
  PP_Var ret = GetOrCreateObjectVarID(object.get());

  VarInfo& info = GetLiveVar(ret)->second;
  info.track_with_no_reference_count++;
  return ret;
}

void PluginVarTracker::StopTrackingObjectWithNoReference(
    const PP_Var& plugin_var) {
  CheckThreadingPreconditions();
  DCHECK(plugin_var.type == PP_VARTYPE_OBJECT);

  VarMap::iterator found = GetLiveVar(plugin_var);
  if (found == live_vars_.end()) {
    NOTREACHED();
    return;
  }

  DCHECK(found->second.track_with_no_reference_count > 0);
  found->second.track_with_no_reference_count--;
  DeleteObjectInfoIfNecessary(found);
}

PP_Var PluginVarTracker::GetHostObject(const PP_Var& plugin_object) const {
  CheckThreadingPreconditions();
  if (plugin_object.type != PP_VARTYPE_OBJECT) {
    NOTREACHED();
    return PP_MakeUndefined();
  }

  Var* var = GetVar(plugin_object);
  ProxyObjectVar* object = var->AsProxyObjectVar();
  if (!object) {
    NOTREACHED();
    return PP_MakeUndefined();
  }

  // Make a var with the host ID.
  PP_Var ret = { PP_VARTYPE_OBJECT };
  ret.value.as_id = object->host_var_id();
  return ret;
}

PluginDispatcher* PluginVarTracker::DispatcherForPluginObject(
    const PP_Var& plugin_object) const {
  CheckThreadingPreconditions();
  if (plugin_object.type != PP_VARTYPE_OBJECT)
    return NULL;

  VarMap::const_iterator found = GetLiveVar(plugin_object);
  if (found == live_vars_.end())
    return NULL;

  ProxyObjectVar* object = found->second.var->AsProxyObjectVar();
  if (!object)
    return NULL;
  return object->dispatcher();
}

void PluginVarTracker::ReleaseHostObject(PluginDispatcher* dispatcher,
                                         const PP_Var& host_object) {
  CheckThreadingPreconditions();
  DCHECK(host_object.type == PP_VARTYPE_OBJECT);

  // Convert the host object to a normal var valid in the plugin.
  HostVarToPluginVarMap::iterator found = host_var_to_plugin_var_.find(
      HostVar(dispatcher, static_cast<int32>(host_object.value.as_id)));
  if (found == host_var_to_plugin_var_.end()) {
    NOTREACHED();
    return;
  }

  // Now just release the object given the plugin var ID.
  ReleaseVar(found->second);
}

PP_Var PluginVarTracker::MakeResourcePPVarFromMessage(
    PP_Instance instance,
    const IPC::Message& creation_message,
    int pending_renderer_id,
    int pending_browser_id) {
  switch (creation_message.type()) {
    case PpapiPluginMsg_FileSystem_CreateFromPendingHost::ID: {
      DCHECK(pending_renderer_id);
      DCHECK(pending_browser_id);
      PP_FileSystemType file_system_type;
      if (!UnpackMessage<PpapiPluginMsg_FileSystem_CreateFromPendingHost>(
               creation_message, &file_system_type)) {
        NOTREACHED() << "Invalid message of type "
                        "PpapiPluginMsg_FileSystem_CreateFromPendingHost";
        return PP_MakeNull();
      }
      // Create a plugin-side resource and attach it to the host resource.
      // Note: This only makes sense when the plugin is out of process (which
      // should always be true when passing resource vars).
      PP_Resource pp_resource =
          (new FileSystemResource(GetConnectionForInstance(instance),
                                  instance,
                                  pending_renderer_id,
                                  pending_browser_id,
                                  file_system_type))->GetReference();
      return MakeResourcePPVar(pp_resource);
    }
    case PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost::ID: {
      DCHECK(pending_renderer_id);
      std::string track_id;
      if (!UnpackMessage<
              PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost>(
          creation_message, &track_id)) {
        NOTREACHED() <<
            "Invalid message of type "
            "PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost";
        return PP_MakeNull();
      }
      PP_Resource pp_resource =
          (new MediaStreamAudioTrackResource(GetConnectionForInstance(instance),
                                             instance,
                                             pending_renderer_id,
                                             track_id))->GetReference();
      return MakeResourcePPVar(pp_resource);
    }
    case PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost::ID: {
      DCHECK(pending_renderer_id);
      std::string track_id;
      if (!UnpackMessage<
              PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost>(
          creation_message, &track_id)) {
        NOTREACHED() <<
            "Invalid message of type "
            "PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost";
        return PP_MakeNull();
      }
      PP_Resource pp_resource =
          (new MediaStreamVideoTrackResource(GetConnectionForInstance(instance),
                                             instance,
                                             pending_renderer_id,
                                             track_id))->GetReference();
      return MakeResourcePPVar(pp_resource);
    }
    default: {
      NOTREACHED() << "Creation message has unexpected type "
                   << creation_message.type();
      return PP_MakeNull();
    }
  }
}

ResourceVar* PluginVarTracker::MakeResourceVar(PP_Resource pp_resource) {
  // The resource 0 returns a null resource var.
  if (!pp_resource)
    return new PluginResourceVar();

  ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker();
  ppapi::Resource* resource = resource_tracker->GetResource(pp_resource);
  // A non-existant resource other than 0 returns NULL.
  if (!resource)
    return NULL;
  return new PluginResourceVar(resource);
}

void PluginVarTracker::DidDeleteInstance(PP_Instance instance) {
  // Calling the destructors on plugin objects may in turn release other
  // objects which will mutate the map out from under us. So do a two-step
  // process of identifying the ones to delete, and then delete them.
  //
  // See the comment above user_data_to_plugin_ in the header file. We assume
  // there aren't that many objects so a brute-force search is reasonable.
  std::vector<void*> user_data_to_delete;
  for (UserDataToPluginImplementedVarMap::const_iterator i =
           user_data_to_plugin_.begin();
       i != user_data_to_plugin_.end();
       ++i) {
    if (i->second.instance == instance)
      user_data_to_delete.push_back(i->first);
  }

  for (size_t i = 0; i < user_data_to_delete.size(); i++) {
    UserDataToPluginImplementedVarMap::iterator found =
        user_data_to_plugin_.find(user_data_to_delete[i]);
    if (found == user_data_to_plugin_.end())
      continue;  // Object removed from list while we were iterating.

    if (!found->second.plugin_object_id) {
      // This object is for the freed instance and the plugin is not holding
      // any references to it. Deallocate immediately.
      CallWhileUnlocked(found->second.ppp_class->Deallocate, found->first);
      user_data_to_plugin_.erase(found);
    } else {
      // The plugin is holding refs to this object. We don't want to call
      // Deallocate since the plugin may be depending on those refs to keep
      // its data alive. To avoid crashes in this case, just clear out the
      // instance to mark it and continue. When the plugin refs go to 0,
      // we'll notice there is no instance and call Deallocate.
      found->second.instance = 0;
    }
  }
}

void PluginVarTracker::DidDeleteDispatcher(PluginDispatcher* dispatcher) {
  for (VarMap::iterator it = live_vars_.begin();
       it != live_vars_.end();
       ++it) {
    if (it->second.var.get() == NULL)
      continue;
    ProxyObjectVar* object = it->second.var->AsProxyObjectVar();
    if (object && object->dispatcher() == dispatcher)
      object->clear_dispatcher();
  }
}

ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) {
  return new PluginArrayBufferVar(size_in_bytes);
}

ArrayBufferVar* PluginVarTracker::CreateShmArrayBuffer(
    uint32 size_in_bytes,
    base::SharedMemoryHandle handle) {
  return new PluginArrayBufferVar(size_in_bytes, handle);
}

void PluginVarTracker::PluginImplementedObjectCreated(
    PP_Instance instance,
    const PP_Var& created_var,
    const PPP_Class_Deprecated* ppp_class,
    void* ppp_class_data) {
  PluginImplementedVar p;
  p.ppp_class = ppp_class;
  p.instance = instance;
  p.plugin_object_id = created_var.value.as_id;
  user_data_to_plugin_[ppp_class_data] = p;

  // Link the user data to the object.
  ProxyObjectVar* object = GetVar(created_var)->AsProxyObjectVar();
  object->set_user_data(ppp_class_data);
}

void PluginVarTracker::PluginImplementedObjectDestroyed(void* user_data) {
  UserDataToPluginImplementedVarMap::iterator found =
      user_data_to_plugin_.find(user_data);
  if (found == user_data_to_plugin_.end()) {
    NOTREACHED();
    return;
  }
  user_data_to_plugin_.erase(found);
}

bool PluginVarTracker::IsPluginImplementedObjectAlive(void* user_data) {
  return user_data_to_plugin_.find(user_data) != user_data_to_plugin_.end();
}

bool PluginVarTracker::ValidatePluginObjectCall(
    const PPP_Class_Deprecated* ppp_class,
    void* user_data) {
  UserDataToPluginImplementedVarMap::iterator found =
      user_data_to_plugin_.find(user_data);
  if (found == user_data_to_plugin_.end())
    return false;
  return found->second.ppp_class == ppp_class;
}

int32 PluginVarTracker::AddVarInternal(Var* var, AddVarRefMode mode) {
  // Normal adding.
  int32 new_id = VarTracker::AddVarInternal(var, mode);

  // Need to add proxy objects to the host var map.
  ProxyObjectVar* proxy_object = var->AsProxyObjectVar();
  if (proxy_object) {
    HostVar host_var(proxy_object->dispatcher(), proxy_object->host_var_id());
    // TODO(teravest): Change to DCHECK when http://crbug.com/276347 is
    // resolved.
    CHECK(host_var_to_plugin_var_.find(host_var) ==
          host_var_to_plugin_var_.end());  // Adding an object twice, use
                                           // FindOrMakePluginVarFromHostVar.
    host_var_to_plugin_var_[host_var] = new_id;
  }
  return new_id;
}

void PluginVarTracker::TrackedObjectGettingOneRef(VarMap::const_iterator iter) {
  ProxyObjectVar* object = iter->second.var->AsProxyObjectVar();
  if (!object) {
    NOTREACHED();
    return;
  }

  DCHECK(iter->second.ref_count == 0);

  // Got an AddRef for an object we have no existing reference for.
  // We need to tell the browser we've taken a ref. This comes up when the
  // browser passes an object as an input param and holds a ref for us.
  // This must be a sync message since otherwise the "addref" will actually
  // occur after the return to the browser of the sync function that
  // presumably sent the object.
  SendAddRefObjectMsg(*object);
}

void PluginVarTracker::ObjectGettingZeroRef(VarMap::iterator iter) {
  ProxyObjectVar* object = iter->second.var->AsProxyObjectVar();
  if (!object) {
    NOTREACHED();
    return;
  }

  // Notify the host we're no longer holding our ref.
  DCHECK(iter->second.ref_count == 0);
  SendReleaseObjectMsg(*object);

  UserDataToPluginImplementedVarMap::iterator found =
      user_data_to_plugin_.find(object->user_data());
  if (found != user_data_to_plugin_.end()) {
    // This object is implemented in the plugin.
    if (found->second.instance == 0) {
      // Instance is destroyed. This means that we'll never get a Deallocate
      // call from the renderer and we should do so now.
      found->second.ppp_class->Deallocate(found->first);
      user_data_to_plugin_.erase(found);
    } else {
      // The plugin is releasing its last reference to an object it implements.
      // Clear the tracking data that links our "plugin implemented object" to
      // the var. If the instance is destroyed and there is no ID, we know that
      // we should just call Deallocate on the object data.
      //
      // See the plugin_object_id declaration for more info.
      found->second.plugin_object_id = 0;
    }
  }

  // This will optionally delete the info from live_vars_.
  VarTracker::ObjectGettingZeroRef(iter);
}

bool PluginVarTracker::DeleteObjectInfoIfNecessary(VarMap::iterator iter) {
  // Get the info before calling the base class's version of this function,
  // which may delete the object.
  ProxyObjectVar* object = iter->second.var->AsProxyObjectVar();
  HostVar host_var(object->dispatcher(), object->host_var_id());

  if (!VarTracker::DeleteObjectInfoIfNecessary(iter))
    return false;

  // Clean up the host var mapping.
  DCHECK(host_var_to_plugin_var_.find(host_var) !=
         host_var_to_plugin_var_.end());
  host_var_to_plugin_var_.erase(host_var);
  return true;
}

PP_Var PluginVarTracker::GetOrCreateObjectVarID(ProxyObjectVar* object) {
  // We can't use object->GetPPVar() because we don't want to affect the
  // refcount, so we have to add everything manually here.
  int32 var_id = object->GetExistingVarID();
  if (!var_id) {
    var_id = AddVarInternal(object, ADD_VAR_CREATE_WITH_NO_REFERENCE);
    object->AssignVarID(var_id);
  }

  PP_Var ret = { PP_VARTYPE_OBJECT };
  ret.value.as_id = var_id;
  return ret;
}

void PluginVarTracker::SendAddRefObjectMsg(
    const ProxyObjectVar& proxy_object) {
  int unused;
  if (proxy_object.dispatcher()) {
    proxy_object.dispatcher()->Send(new PpapiHostMsg_PPBVar_AddRefObject(
        API_ID_PPB_VAR_DEPRECATED, proxy_object.host_var_id(), &unused));
  }
}

void PluginVarTracker::SendReleaseObjectMsg(
    const ProxyObjectVar& proxy_object) {
  if (proxy_object.dispatcher()) {
    proxy_object.dispatcher()->Send(new PpapiHostMsg_PPBVar_ReleaseObject(
        API_ID_PPB_VAR_DEPRECATED, proxy_object.host_var_id()));
  }
}

scoped_refptr<ProxyObjectVar> PluginVarTracker::FindOrMakePluginVarFromHostVar(
    const PP_Var& var,
    PluginDispatcher* dispatcher) {
  DCHECK(var.type == PP_VARTYPE_OBJECT);
  HostVar host_var(dispatcher, var.value.as_id);

  HostVarToPluginVarMap::iterator found =
      host_var_to_plugin_var_.find(host_var);
  if (found == host_var_to_plugin_var_.end()) {
    // Create a new object.
    return scoped_refptr<ProxyObjectVar>(
        new ProxyObjectVar(dispatcher, static_cast<int32>(var.value.as_id)));
  }

  // Have this host var, look up the object.
  VarMap::iterator ret = live_vars_.find(found->second);

  // We CHECK here because we currently don't fall back sanely.
  // This may be involved in a NULL dereference. http://crbug.com/276347
  CHECK(ret != live_vars_.end());

  // All objects should be proxy objects.
  DCHECK(ret->second.var->AsProxyObjectVar());
  return scoped_refptr<ProxyObjectVar>(ret->second.var->AsProxyObjectVar());
}

int PluginVarTracker::TrackSharedMemoryHandle(PP_Instance instance,
                                              base::SharedMemoryHandle handle,
                                              uint32 size_in_bytes) {
  NOTREACHED();
  return -1;
}

bool PluginVarTracker::StopTrackingSharedMemoryHandle(
    int id,
    PP_Instance instance,
    base::SharedMemoryHandle* handle,
    uint32* size_in_bytes) {
  NOTREACHED();
  return false;
}

}  // namesace proxy
}  // namespace ppapi
