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

#include <stddef.h>

#include <utility>

#include "base/check.h"
#include "base/notreached.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/host_factory.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/instance_message_filter.h"
#include "ppapi/host/resource_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
#include "ppapi/proxy/serialized_handle.h"
#include "ppapi/shared_impl/host_resource.h"

namespace ppapi {
namespace host {

using proxy::SerializedHandle;

namespace {

// Put a cap on the maximum number of resources so we don't explode if the
// renderer starts spamming us.
const size_t kMaxResourcesPerPlugin = 1 << 14;

}  // namespace

PpapiHost::PpapiHost(IPC::Sender* sender,
                     const PpapiPermissions& perms)
    : sender_(sender),
      permissions_(perms),
      next_pending_resource_host_id_(1) {
}

PpapiHost::~PpapiHost() {
  // Delete these explicitly before destruction since then the host is still
  // technically alive in case one of the filters accesses us from the
  // destructor.
  instance_message_filters_.clear();

  // The resources may also want to use us in their destructors.
  resources_.clear();
  pending_resource_hosts_.clear();
}

bool PpapiHost::Send(IPC::Message* msg) {
  return sender_->Send(msg);
}

bool PpapiHost::OnMessageReceived(const IPC::Message& msg) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(PpapiHost, msg)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCall,
                        OnHostMsgResourceCall)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_InProcessResourceCall,
                        OnHostMsgInProcessResourceCall)
    IPC_MESSAGE_HANDLER_DELAY_REPLY(PpapiHostMsg_ResourceSyncCall,
                                    OnHostMsgResourceSyncCall)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceCreated,
                        OnHostMsgResourceCreated)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_AttachToPendingHost,
                        OnHostMsgAttachToPendingHost)
    IPC_MESSAGE_HANDLER(PpapiHostMsg_ResourceDestroyed,
                        OnHostMsgResourceDestroyed)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  if (!handled) {
    for (size_t i = 0; i < instance_message_filters_.size(); i++) {
      if (instance_message_filters_[i]->OnInstanceMessageReceived(msg)) {
        handled = true;
        break;
      }
    }
  }

  return handled;
}

void PpapiHost::SendReply(const ReplyMessageContext& context,
                          const IPC::Message& msg) {
  TRACE_EVENT2("ppapi proxy", "PpapiHost::SendReply",
               "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
               "Line", IPC_MESSAGE_ID_LINE(msg.type()));
  if (context.sync_reply_msg) {
    PpapiHostMsg_ResourceSyncCall::WriteReplyParams(context.sync_reply_msg,
                                                    context.params, msg);
    Send(context.sync_reply_msg);
  } else {
    if (context.routing_id != MSG_ROUTING_NONE) {
      Send(new PpapiHostMsg_InProcessResourceReply(context.routing_id,
                                                   context.params,
                                                   msg));
    } else {
      Send(new PpapiPluginMsg_ResourceReply(context.params, msg));
    }
  }
}

void PpapiHost::SendUnsolicitedReply(PP_Resource resource,
                                     const IPC::Message& msg) {
  std::vector<SerializedHandle> empty;
  SendUnsolicitedReplyWithHandles(resource, msg, &empty);
}

void PpapiHost::SendUnsolicitedReplyWithHandles(
    PP_Resource resource,
    const IPC::Message& msg,
    std::vector<SerializedHandle>* handles) {
  TRACE_EVENT2("ppapi proxy", "PpapiHost::SendUnsolicitedReplyWithHandles",
               "Class", IPC_MESSAGE_ID_CLASS(msg.type()),
               "Line", IPC_MESSAGE_ID_LINE(msg.type()));
  DCHECK(resource);  // If this fails, host is probably pending.
  proxy::ResourceMessageReplyParams params(resource, 0);
  for (auto& handle : *handles)
    params.AppendHandle(std::move(handle));
  Send(new PpapiPluginMsg_ResourceReply(params, msg));
}

std::unique_ptr<ResourceHost> PpapiHost::CreateResourceHost(
    PP_Resource resource,
    PP_Instance instance,
    const IPC::Message& nested_msg) {
  std::unique_ptr<ResourceHost> resource_host;
  DCHECK(!host_factory_filters_.empty());  // Caller forgot to add a factory.
  for (size_t i = 0; i < host_factory_filters_.size(); i++) {
    resource_host = host_factory_filters_[i]->CreateResourceHost(
        this, resource, instance, nested_msg);
    if (resource_host.get())
      break;
  }
  return resource_host;
}

int PpapiHost::AddPendingResourceHost(
    std::unique_ptr<ResourceHost> resource_host) {
  // The resource ID should not be assigned.
  if (!resource_host.get() || resource_host->pp_resource() != 0) {
    NOTREACHED();
    return 0;
  }

  if (pending_resource_hosts_.size() + resources_.size()
      >= kMaxResourcesPerPlugin) {
    return 0;
  }

  int pending_id = next_pending_resource_host_id_++;
  pending_resource_hosts_[pending_id] = std::move(resource_host);
  return pending_id;
}

void PpapiHost::AddHostFactoryFilter(std::unique_ptr<HostFactory> filter) {
  host_factory_filters_.push_back(std::move(filter));
}

void PpapiHost::AddInstanceMessageFilter(
    std::unique_ptr<InstanceMessageFilter> filter) {
  instance_message_filters_.push_back(std::move(filter));
}

void PpapiHost::OnHostMsgResourceCall(
    const proxy::ResourceMessageCallParams& params,
    const IPC::Message& nested_msg) {
  TRACE_EVENT2("ppapi proxy", "PpapiHost::OnHostMsgResourceCall",
               "Class", IPC_MESSAGE_ID_CLASS(nested_msg.type()),
               "Line", IPC_MESSAGE_ID_LINE(nested_msg.type()));
  HostMessageContext context(params);
  HandleResourceCall(params, nested_msg, &context);
}

void PpapiHost::OnHostMsgInProcessResourceCall(
    int routing_id,
    const proxy::ResourceMessageCallParams& params,
    const IPC::Message& nested_msg) {
  TRACE_EVENT2("ppapi proxy", "PpapiHost::OnHostMsgInProcessResourceCall",
               "Class", IPC_MESSAGE_ID_CLASS(nested_msg.type()),
               "Line", IPC_MESSAGE_ID_LINE(nested_msg.type()));
  HostMessageContext context(routing_id, params);
  HandleResourceCall(params, nested_msg, &context);
}

void PpapiHost::OnHostMsgResourceSyncCall(
    const proxy::ResourceMessageCallParams& params,
    const IPC::Message& nested_msg,
    IPC::Message* reply_msg) {
  TRACE_EVENT2("ppapi proxy", "PpapiHost::OnHostMsgResourceSyncCall",
               "Class", IPC_MESSAGE_ID_CLASS(nested_msg.type()),
               "Line", IPC_MESSAGE_ID_LINE(nested_msg.type()));
  // Sync messages should always have callback set because they always expect
  // a reply from the host.
  DCHECK(params.has_callback());
  // Stash the |reply_msg| in the context so that it can be used to reply
  // to the sync message.
  HostMessageContext context(params, reply_msg);
  HandleResourceCall(params, nested_msg, &context);
}

void PpapiHost::HandleResourceCall(
    const proxy::ResourceMessageCallParams& params,
    const IPC::Message& nested_msg,
    HostMessageContext* context) {
  ResourceHost* resource_host = GetResourceHost(params.pp_resource());
  if (resource_host) {
    // CAUTION: Handling the message may cause the destruction of this object.
    resource_host->HandleMessage(nested_msg, context);
  } else {
    if (context->params.has_callback()) {
      ReplyMessageContext reply_context = context->MakeReplyMessageContext();
      reply_context.params.set_result(PP_ERROR_BADRESOURCE);
      SendReply(reply_context, context->reply_msg);
    }
  }
}

void PpapiHost::OnHostMsgResourceCreated(
    const proxy::ResourceMessageCallParams& params,
    PP_Instance instance,
    const IPC::Message& nested_msg) {
  TRACE_EVENT2("ppapi proxy", "PpapiHost::OnHostMsgResourceCreated",
               "Class", IPC_MESSAGE_ID_CLASS(nested_msg.type()),
               "Line", IPC_MESSAGE_ID_LINE(nested_msg.type()));

  if (pending_resource_hosts_.size() + resources_.size()
      >= kMaxResourcesPerPlugin) {
    return;
  }

  // Run through all filters until one grabs this message.
  std::unique_ptr<ResourceHost> resource_host =
      CreateResourceHost(params.pp_resource(), instance, nested_msg);

  if (!resource_host.get()) {
    NOTREACHED();
    return;
  }

  // Resource should have been assigned a nonzero PP_Resource.
  DCHECK(resource_host->pp_resource());

  resources_[params.pp_resource()] = std::move(resource_host);
}

void PpapiHost::OnHostMsgAttachToPendingHost(PP_Resource pp_resource,
                                             int pending_host_id) {
  PendingHostResourceMap::iterator found =
      pending_resource_hosts_.find(pending_host_id);
  if (found == pending_resource_hosts_.end()) {
    // Plugin sent a bad ID.
    NOTREACHED();
    return;
  }
  found->second->SetPPResourceForPendingHost(pp_resource);
  resources_[pp_resource] = std::move(found->second);
  pending_resource_hosts_.erase(found);
}

void PpapiHost::OnHostMsgResourceDestroyed(PP_Resource resource) {
  ResourceMap::iterator found = resources_.find(resource);
  if (found == resources_.end()) {
    NOTREACHED();
    return;
  }
  // Invoking the HostResource destructor might result in looking up the
  // PP_Resource in resources_. std::map is not well specified as to whether the
  // element will be there or not. Therefore, we delay destruction of the
  // HostResource until after we've made sure the map no longer contains
  // |resource|.
  std::unique_ptr<ResourceHost> delete_at_end_of_scope(
      std::move(found->second));
  resources_.erase(found);
}

ResourceHost* PpapiHost::GetResourceHost(PP_Resource resource) const {
  ResourceMap::const_iterator found = resources_.find(resource);
  return found == resources_.end() ? NULL : found->second.get();
}

}  // namespace host
}  // namespace ppapi
