// 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 "content/renderer/pepper/host_globals.h"

#include <limits>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/plugin_module.h"
#include "content/renderer/render_thread_impl.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/id_assignment.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebPluginContainer.h"

using ppapi::CheckIdType;
using ppapi::MakeTypedId;
using ppapi::PPIdType;
using ppapi::ResourceTracker;
using blink::WebConsoleMessage;
using blink::WebLocalFrame;
using blink::WebPluginContainer;
using blink::WebString;

namespace content {

namespace {

typedef std::set<WebPluginContainer*> ContainerSet;

// Adds all WebPluginContainers associated with the given module to the set.
void GetAllContainersForModule(PluginModule* module, ContainerSet* containers) {
  const PluginModule::PluginInstanceSet& instances = module->GetAllInstances();
  for (PluginModule::PluginInstanceSet::const_iterator i = instances.begin();
       i != instances.end();
       ++i) {
    WebPluginContainer* container = (*i)->container();
    // If "Delete" is called on an instance, the instance sets its container to
    // NULL, but the instance may actually outlive its container. Callers of
    // GetAllContainersForModule only want to know about valid containers.
    if (container)
      containers->insert(container);
  }
}

WebConsoleMessage::Level LogLevelToWebLogLevel(PP_LogLevel level) {
  switch (level) {
    case PP_LOGLEVEL_TIP:
      return WebConsoleMessage::LevelDebug;
    case PP_LOGLEVEL_LOG:
      return WebConsoleMessage::LevelLog;
    case PP_LOGLEVEL_WARNING:
      return WebConsoleMessage::LevelWarning;
    case PP_LOGLEVEL_ERROR:
    default:
      return WebConsoleMessage::LevelError;
  }
}

WebConsoleMessage MakeLogMessage(PP_LogLevel level,
                                 const std::string& source,
                                 const std::string& message) {
  std::string result = source;
  if (!result.empty())
    result.append(": ");
  result.append(message);
  return WebConsoleMessage(LogLevelToWebLogLevel(level),
                           WebString(base::UTF8ToUTF16(result)));
}

}  // namespace

HostGlobals* HostGlobals::host_globals_ = NULL;

HostGlobals::HostGlobals()
    : ppapi::PpapiGlobals(),
      resource_tracker_(ResourceTracker::SINGLE_THREADED) {
  DCHECK(!host_globals_);
  host_globals_ = this;
  // We do not support calls off of the main thread on the host side, and thus
  // do not lock.
  ppapi::ProxyLock::DisableLocking();
}

HostGlobals::~HostGlobals() {
  DCHECK(host_globals_ == this || !host_globals_);
  host_globals_ = NULL;
}

ppapi::ResourceTracker* HostGlobals::GetResourceTracker() {
  return &resource_tracker_;
}

ppapi::VarTracker* HostGlobals::GetVarTracker() { return &host_var_tracker_; }

ppapi::CallbackTracker* HostGlobals::GetCallbackTrackerForInstance(
    PP_Instance instance) {
  InstanceMap::iterator found = instance_map_.find(instance);
  if (found == instance_map_.end())
    return NULL;
  return found->second->module()->GetCallbackTracker().get();
}

ppapi::thunk::PPB_Instance_API* HostGlobals::GetInstanceAPI(
    PP_Instance instance) {
  // The InstanceAPI is just implemented by the PluginInstance object.
  return GetInstance(instance);
}

ppapi::thunk::ResourceCreationAPI* HostGlobals::GetResourceCreationAPI(
    PP_Instance pp_instance) {
  PepperPluginInstanceImpl* instance = GetInstance(pp_instance);
  if (!instance)
    return NULL;
  return &instance->resource_creation();
}

PP_Module HostGlobals::GetModuleForInstance(PP_Instance instance) {
  PepperPluginInstanceImpl* inst = GetInstance(instance);
  if (!inst)
    return 0;
  return inst->module()->pp_module();
}

std::string HostGlobals::GetCmdLine() {
  return CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
      switches::kPpapiFlashArgs);
}

void HostGlobals::PreCacheFontForFlash(const void* logfontw) {
  // Not implemented in-process.
}

void HostGlobals::LogWithSource(PP_Instance instance,
                                PP_LogLevel level,
                                const std::string& source,
                                const std::string& value) {
  PepperPluginInstanceImpl* instance_object =
      HostGlobals::Get()->GetInstance(instance);
  if (instance_object) {
    instance_object->container()
        ->element()
        .document()
        .frame()
        ->addMessageToConsole(MakeLogMessage(level, source, value));
  } else {
    BroadcastLogWithSource(0, level, source, value);
  }
}

void HostGlobals::BroadcastLogWithSource(PP_Module pp_module,
                                         PP_LogLevel level,
                                         const std::string& source,
                                         const std::string& value) {
  // Get the unique containers associated with the broadcast. This prevents us
  // from sending the same message to the same console when there are two
  // instances on the page.
  ContainerSet containers;
  PluginModule* module = GetModule(pp_module);
  if (module) {
    GetAllContainersForModule(module, &containers);
  } else {
    // Unknown module, get containers for all modules.
    for (ModuleMap::const_iterator i = module_map_.begin();
         i != module_map_.end();
         ++i) {
      GetAllContainersForModule(i->second, &containers);
    }
  }

  WebConsoleMessage message = MakeLogMessage(level, source, value);
  for (ContainerSet::iterator i = containers.begin(); i != containers.end();
       ++i) {
    WebLocalFrame* frame = (*i)->element().document().frame();
    if (frame)
      frame->addMessageToConsole(message);
  }
}

base::TaskRunner* HostGlobals::GetFileTaskRunner() {
  return RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get();
}

ppapi::MessageLoopShared* HostGlobals::GetCurrentMessageLoop() { return NULL; }

PP_Module HostGlobals::AddModule(PluginModule* module) {
#ifndef NDEBUG
  // Make sure we're not adding one more than once.
  for (ModuleMap::const_iterator i = module_map_.begin();
       i != module_map_.end();
       ++i)
    DCHECK(i->second != module);
#endif

  // See AddInstance.
  PP_Module new_module;
  do {
    new_module = MakeTypedId(static_cast<PP_Module>(base::RandUint64()),
                             ppapi::PP_ID_TYPE_MODULE);
  } while (!new_module || module_map_.find(new_module) != module_map_.end());
  module_map_[new_module] = module;
  return new_module;
}

void HostGlobals::ModuleDeleted(PP_Module module) {
  DLOG_IF(ERROR, !CheckIdType(module, ppapi::PP_ID_TYPE_MODULE))
      << module << " is not a PP_Module.";
  ModuleMap::iterator found = module_map_.find(module);
  if (found == module_map_.end()) {
    NOTREACHED();
    return;
  }
  module_map_.erase(found);
}

PluginModule* HostGlobals::GetModule(PP_Module module) {
  DLOG_IF(ERROR, !CheckIdType(module, ppapi::PP_ID_TYPE_MODULE))
      << module << " is not a PP_Module.";
  ModuleMap::iterator found = module_map_.find(module);
  if (found == module_map_.end())
    return NULL;
  return found->second;
}

PP_Instance HostGlobals::AddInstance(PepperPluginInstanceImpl* instance) {
  DCHECK(instance_map_.find(instance->pp_instance()) == instance_map_.end());

  // Use a random number for the instance ID. This helps prevent some
  // accidents. See also AddModule below.
  //
  // Need to make sure the random number isn't a duplicate or 0.
  PP_Instance new_instance;
  do {
    new_instance = MakeTypedId(static_cast<PP_Instance>(base::RandUint64()),
                               ppapi::PP_ID_TYPE_INSTANCE);
  } while (!new_instance ||
           instance_map_.find(new_instance) != instance_map_.end() ||
           !instance->module()->ReserveInstanceID(new_instance));

  instance_map_[new_instance] = instance;

  resource_tracker_.DidCreateInstance(new_instance);
  return new_instance;
}

void HostGlobals::InstanceDeleted(PP_Instance instance) {
  resource_tracker_.DidDeleteInstance(instance);
  host_var_tracker_.DidDeleteInstance(instance);
  instance_map_.erase(instance);
}

void HostGlobals::InstanceCrashed(PP_Instance instance) {
  resource_tracker_.DidDeleteInstance(instance);
  host_var_tracker_.DidDeleteInstance(instance);
}

PepperPluginInstanceImpl* HostGlobals::GetInstance(PP_Instance instance) {
  DLOG_IF(ERROR, !CheckIdType(instance, ppapi::PP_ID_TYPE_INSTANCE))
      << instance << " is not a PP_Instance.";
  InstanceMap::iterator found = instance_map_.find(instance);
  if (found == instance_map_.end())
    return NULL;
  return found->second;
}

bool HostGlobals::IsHostGlobals() const { return true; }

}  // namespace content
