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

#include <stddef.h>

#include <tuple>

#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"

namespace ppapi {
namespace proxy {

namespace {

// Backend for GetAllResource[Calls|Replies]Matching.
template <class WrapperMessage, class Params>
std::vector<std::pair<Params, IPC::Message>> GetAllResourceMessagesMatching(
    const ResourceMessageTestSink& sink,
    uint32_t id) {
  std::vector<std::pair<Params, IPC::Message> > result;
  for (size_t i = 0; i < sink.message_count(); i++) {
    const IPC::Message* msg = sink.GetMessageAt(i);
    if (msg->type() == WrapperMessage::ID) {
      typename WrapperMessage::Param params;
      WrapperMessage::Read(msg, &params);
      Params cur_params = std::get<0>(params);
      IPC::Message cur_msg = std::get<1>(params);
      if (cur_msg.type() == id) {
        result.push_back(std::make_pair(cur_params, cur_msg));
      }
    }
  }
  return result;
}

}  // namespace

ResourceMessageTestSink::ResourceMessageTestSink() {
}

ResourceMessageTestSink::~ResourceMessageTestSink() {
}

bool ResourceMessageTestSink::Send(IPC::Message* msg) {
  int message_id = 0;
  std::unique_ptr<IPC::MessageReplyDeserializer> reply_deserializer;
  if (msg->is_sync()) {
    reply_deserializer.reset(
        static_cast<IPC::SyncMessage*>(msg)->GetReplyDeserializer());
    message_id = IPC::SyncMessage::GetMessageId(*msg);
  }
  bool result = IPC::TestSink::Send(msg);  // Deletes |msg|.
  if (sync_reply_msg_.get()) {
    // |sync_reply_msg_| should always be a reply to the pending sync message.
    DCHECK(IPC::SyncMessage::IsMessageReplyTo(*sync_reply_msg_.get(),
                                              message_id));
    reply_deserializer->SerializeOutputParameters(*sync_reply_msg_.get());
    sync_reply_msg_.reset(NULL);
  }
  return result;
}

void ResourceMessageTestSink::SetSyncReplyMessage(IPC::Message* reply_msg) {
  DCHECK(!sync_reply_msg_.get());
  sync_reply_msg_.reset(reply_msg);
}

bool ResourceMessageTestSink::GetFirstResourceCallMatching(
    uint32_t id,
    ResourceMessageCallParams* params,
    IPC::Message* nested_msg) const {
  ResourceCallVector matching_messages =
      GetAllResourceMessagesMatching<PpapiHostMsg_ResourceCall,
                                     ResourceMessageCallParams>(*this, id);
  if (matching_messages.empty())
    return false;

  *params = matching_messages[0].first;
  *nested_msg = matching_messages[0].second;
  return true;
}

bool ResourceMessageTestSink::GetFirstResourceReplyMatching(
    uint32_t id,
    ResourceMessageReplyParams* params,
    IPC::Message* nested_msg) {
  ResourceReplyVector matching_messages =
      GetAllResourceMessagesMatching<PpapiPluginMsg_ResourceReply,
                                     ResourceMessageReplyParams>(*this, id);
  if (matching_messages.empty())
    return false;

  *params = matching_messages[0].first;
  *nested_msg = matching_messages[0].second;
  return true;
}

ResourceMessageTestSink::ResourceCallVector
ResourceMessageTestSink::GetAllResourceCallsMatching(uint32_t id) {
  return GetAllResourceMessagesMatching<PpapiHostMsg_ResourceCall,
                                        ResourceMessageCallParams>(*this, id);
}

ResourceMessageTestSink::ResourceReplyVector
ResourceMessageTestSink::GetAllResourceRepliesMatching(uint32_t id) {
  return GetAllResourceMessagesMatching<PpapiPluginMsg_ResourceReply,
                                        ResourceMessageReplyParams>(*this, id);
}

ResourceSyncCallHandler::ResourceSyncCallHandler(
    ResourceMessageTestSink* test_sink,
    uint32_t incoming_type,
    int32_t result,
    const IPC::Message& reply_msg)
    : test_sink_(test_sink),
      incoming_type_(incoming_type),
      result_(result),
      reply_msg_(reply_msg) {}

ResourceSyncCallHandler::~ResourceSyncCallHandler() {
}

bool ResourceSyncCallHandler::OnMessageReceived(const IPC::Message& msg) {
  if (msg.type() != PpapiHostMsg_ResourceSyncCall::ID)
    return false;
  PpapiHostMsg_ResourceSyncCall::Schema::SendParam send_params;
  bool success = PpapiHostMsg_ResourceSyncCall::ReadSendParam(
      &msg, &send_params);
  DCHECK(success);
  ResourceMessageCallParams call_params = std::get<0>(send_params);
  IPC::Message call_msg = std::get<1>(send_params);
  if (call_msg.type() != incoming_type_)
    return false;
  IPC::Message* wrapper_reply_msg = IPC::SyncMessage::GenerateReply(&msg);
  ResourceMessageReplyParams reply_params(call_params.pp_resource(),
                                          call_params.sequence());
  reply_params.set_result(result_);
  if (serialized_handle_)
    reply_params.AppendHandle(std::move(*serialized_handle_));
  PpapiHostMsg_ResourceSyncCall::WriteReplyParams(
      wrapper_reply_msg, reply_params, reply_msg_);
  test_sink_->SetSyncReplyMessage(wrapper_reply_msg);

  // Stash a copy of the message for inspection later.
  last_handled_msg_ = call_msg;
  return true;
}

void ResourceSyncCallHandler::set_serialized_handle(
    std::unique_ptr<SerializedHandle> serialized_handle) {
  serialized_handle_ = std::move(serialized_handle);
}

}  // namespace proxy
}  // namespace ppapi
