// 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 "base/logging.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/shared_impl/host_resource.h"

namespace ppapi {
namespace host {

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) {
  TRACE_EVENT2("ppapi proxy", "PpapiHost::SendUnsolicitedReply",
               "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);
  Send(new PpapiPluginMsg_ResourceReply(params, msg));
}

scoped_ptr<ResourceHost> PpapiHost::CreateResourceHost(
    const proxy::ResourceMessageCallParams& params,
    PP_Instance instance,
    const IPC::Message& nested_msg) {
  scoped_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, params, instance, nested_msg).Pass();
    if (resource_host.get())
      break;
  }
  return resource_host.Pass();
}

int PpapiHost::AddPendingResourceHost(scoped_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] =
      linked_ptr<ResourceHost>(resource_host.release());
  return pending_id;
}

void PpapiHost::AddHostFactoryFilter(scoped_ptr<HostFactory> filter) {
  host_factory_filters_.push_back(filter.release());
}

void PpapiHost::AddInstanceMessageFilter(
    scoped_ptr<InstanceMessageFilter> filter) {
  instance_message_filters_.push_back(filter.release());
}

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.
  scoped_ptr<ResourceHost> resource_host = CreateResourceHost(params, 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()] =
      linked_ptr<ResourceHost>(resource_host.release());
}

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] = 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|.
  linked_ptr<ResourceHost> delete_at_end_of_scope(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
