// Copyright 2014 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/nacl_irt/ppapi_dispatcher.h"

#include <stddef.h>

#include <map>
#include <set>

#include "base/command_line.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "build/build_config.h"
#include "components/tracing/child/child_trace_message_filter.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_logging.h"
#include "ipc/ipc_message.h"
#include "ppapi/c/ppp.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/nacl_irt/manifest_service.h"
#include "ppapi/nacl_irt/plugin_startup.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/plugin_message_filter.h"
#include "ppapi/proxy/plugin_proxy_delegate.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_reply_thread_registrar.h"

namespace ppapi {

PpapiDispatcher::PpapiDispatcher(
    scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
    base::WaitableEvent* shutdown_event,
    IPC::ChannelHandle browser_ipc_handle,
    IPC::ChannelHandle renderer_ipc_handle)
    : next_plugin_dispatcher_id_(0),
      task_runner_(io_task_runner),
      shutdown_event_(shutdown_event),
      renderer_ipc_handle_(renderer_ipc_handle) {
  proxy::PluginGlobals* globals = proxy::PluginGlobals::Get();
  // Delay initializing the SyncChannel until after we add filters. This
  // ensures that the filters won't miss any messages received by
  // the channel.
  channel_ =
      IPC::SyncChannel::Create(this, GetIPCTaskRunner(), GetShutdownEvent());
  scoped_refptr<ppapi::proxy::PluginMessageFilter> plugin_filter(
      new ppapi::proxy::PluginMessageFilter(
          NULL, globals->resource_reply_thread_registrar()));
  channel_->AddFilter(plugin_filter.get());
  globals->RegisterResourceMessageFilters(plugin_filter.get());

  channel_->AddFilter(new tracing::ChildTraceMessageFilter(task_runner_.get()));
  channel_->Init(browser_ipc_handle, IPC::Channel::MODE_SERVER, true);
}

base::SingleThreadTaskRunner* PpapiDispatcher::GetIPCTaskRunner() {
  return task_runner_.get();
}

base::WaitableEvent* PpapiDispatcher::GetShutdownEvent() {
  return shutdown_event_;
}

IPC::PlatformFileForTransit PpapiDispatcher::ShareHandleWithRemote(
    base::PlatformFile handle,
    base::ProcessId peer_pid,
    bool should_close_source) {
  return IPC::InvalidPlatformFileForTransit();
}

base::SharedMemoryHandle PpapiDispatcher::ShareSharedMemoryHandleWithRemote(
    const base::SharedMemoryHandle& handle,
    base::ProcessId remote_pid) {
  return base::SharedMemoryHandle();
}

std::set<PP_Instance>* PpapiDispatcher::GetGloballySeenInstanceIDSet() {
  return &instances_;
}

uint32_t PpapiDispatcher::Register(proxy::PluginDispatcher* plugin_dispatcher) {
  if (!plugin_dispatcher ||
      plugin_dispatchers_.size() >= std::numeric_limits<uint32_t>::max()) {
    return 0;
  }

  uint32_t id = 0;
  do {
    // Although it is unlikely, make sure that we won't cause any trouble
    // when the counter overflows.
    id = next_plugin_dispatcher_id_++;
  } while (id == 0 ||
           plugin_dispatchers_.find(id) != plugin_dispatchers_.end());
  plugin_dispatchers_[id] = plugin_dispatcher;
  return id;
}

void PpapiDispatcher::Unregister(uint32_t plugin_dispatcher_id) {
  plugin_dispatchers_.erase(plugin_dispatcher_id);
}

IPC::Sender* PpapiDispatcher::GetBrowserSender() {
  return this;
}

std::string PpapiDispatcher::GetUILanguage() {
  NOTIMPLEMENTED();
  return std::string();
}

void PpapiDispatcher::PreCacheFontForFlash(const void* logfontw) {
  NOTIMPLEMENTED();
}

void PpapiDispatcher::SetActiveURL(const std::string& url) {
  NOTIMPLEMENTED();
}

PP_Resource PpapiDispatcher::CreateBrowserFont(
    proxy::Connection connection,
    PP_Instance instance,
    const PP_BrowserFont_Trusted_Description& desc,
    const Preferences& prefs) {
  NOTIMPLEMENTED();
  return 0;
}

bool PpapiDispatcher::OnMessageReceived(const IPC::Message& msg) {
  IPC_BEGIN_MESSAGE_MAP(PpapiDispatcher, msg)
    IPC_MESSAGE_HANDLER(PpapiMsg_InitializeNaClDispatcher,
                        OnMsgInitializeNaClDispatcher)
    // All other messages are simply forwarded to a PluginDispatcher.
    IPC_MESSAGE_UNHANDLED(OnPluginDispatcherMessageReceived(msg))
  IPC_END_MESSAGE_MAP()
  return true;
}

void PpapiDispatcher::OnChannelError() {
  exit(1);
}

bool PpapiDispatcher::Send(IPC::Message* msg) {
  return channel_->Send(msg);
}

void PpapiDispatcher::OnMsgInitializeNaClDispatcher(
    const PpapiNaClPluginArgs& args) {
  static bool command_line_and_logging_initialized = false;
  if (command_line_and_logging_initialized) {
    LOG(FATAL) << "InitializeNaClDispatcher must be called once per plugin.";
    return;
  }

  command_line_and_logging_initialized = true;
  base::CommandLine::Init(0, NULL);
  for (size_t i = 0; i < args.switch_names.size(); ++i) {
    DCHECK(i < args.switch_values.size());
    base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
        args.switch_names[i], args.switch_values[i]);
  }
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
  logging::InitLogging(settings);

  // Tell the process-global GetInterface which interfaces it can return to the
  // plugin.
  proxy::InterfaceList::SetProcessGlobalPermissions(args.permissions);

  int32_t error = ::PPP_InitializeModule(
      0 /* module */,
      &proxy::PluginDispatcher::GetBrowserInterface);
  if (error)
    ::exit(error);

  proxy::PluginDispatcher* dispatcher =
      new proxy::PluginDispatcher(::PPP_GetInterface, args.permissions,
                                  args.off_the_record);
  if (!dispatcher->InitPluginWithChannel(this, base::kNullProcessId,
                                         renderer_ipc_handle_, false)) {
    delete dispatcher;
    return;
  }
  // From here, the dispatcher will manage its own lifetime according to the
  // lifetime of the attached channel.

  // Notify the renderer process, if necessary.
  ManifestService* manifest_service = GetManifestService();
  if (manifest_service)
    manifest_service->StartupInitializationComplete();
}

void PpapiDispatcher::OnPluginDispatcherMessageReceived(
    const IPC::Message& msg) {
  // The first parameter should be a plugin dispatcher ID.
  base::PickleIterator iter(msg);
  uint32_t id = 0;
  if (!iter.ReadUInt32(&id)) {
    NOTREACHED();
    return;
  }
  std::map<uint32_t, proxy::PluginDispatcher*>::iterator dispatcher =
      plugin_dispatchers_.find(id);
  if (dispatcher != plugin_dispatchers_.end())
    dispatcher->second->OnMessageReceived(msg);
}

}  // namespace ppapi
