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

#include <string.h>
#include <algorithm>
#include <map>
#include <sstream>

#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/file_system.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_array.h"
#include "ppapi/cpp/var_array_buffer.h"
#include "ppapi/cpp/var_dictionary.h"
#include "ppapi/tests/pp_thread.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

// Windows defines 'PostMessage', so we have to undef it.
#ifdef PostMessage
#undef PostMessage
#endif

REGISTER_TEST_CASE(PostMessage);

namespace {

const char kTestFilename[] = "testfile.txt";
const char kTestString[] = "Hello world!";
const bool kTestBool = true;
const int32_t kTestInt = 42;
const double kTestDouble = 42.0;

// On Windows XP bots, the NonMainThread test can run very slowly. So we dial
// back the number of threads & messages when running on Windows.
#ifdef PPAPI_OS_WIN
const int32_t kThreadsToRun = 2;
const int32_t kMessagesToSendPerThread = 5;
#else
const int32_t kThreadsToRun = 4;
const int32_t kMessagesToSendPerThread = 10;
#endif

// The struct that invoke_post_message_thread_func expects for its argument.
// It includes the instance on which to invoke PostMessage, and the value to
// pass to PostMessage.
struct InvokePostMessageThreadArg {
  InvokePostMessageThreadArg(pp::Instance* i, const pp::Var& v)
      : instance(i), value_to_send(v) {}
  pp::Instance* instance;
  pp::Var value_to_send;
};

void InvokePostMessageThreadFunc(void* user_data) {
  InvokePostMessageThreadArg* arg =
      static_cast<InvokePostMessageThreadArg*>(user_data);
  for (int32_t i = 0; i < kMessagesToSendPerThread; ++i)
    arg->instance->PostMessage(arg->value_to_send);
  delete arg;
}

// TODO(raymes): Consider putting something like this into pp::Var.
bool VarsEqual(const pp::Var& expected,
               const pp::Var& actual,
               std::map<int64_t, int64_t>* visited_ids) {
  if (expected.pp_var().type != actual.pp_var().type) {
    if (!expected.is_number() && !actual.is_number())
      return false;
  }
  // TODO(raymes): Implement a pp::Var::IsRefCounted() function.
  if (expected.pp_var().type > PP_VARTYPE_DOUBLE) {
    std::map<int64_t, int64_t>::const_iterator it =
        visited_ids->find(expected.pp_var().value.as_id);
    if (it != visited_ids->end()) {
      if (it->second == actual.pp_var().value.as_id)
        return true;
      return false;
    }
    // Round-tripping reference graphs with strings will not necessarily
    // result in isomorphic graphs. This is because string vars are converted
    // to string primitives in JS which cannot be referenced.
    if (!expected.is_string()) {
      (*visited_ids)[expected.pp_var().value.as_id] =
          actual.pp_var().value.as_id;
    }
  }

  if (expected.is_number()) {
    return fabs(expected.AsDouble() - actual.AsDouble()) < 1.0e-4;
  } else if (expected.is_array()) {
    pp::VarArray expected_array(expected);
    pp::VarArray actual_array(actual);
    if (expected_array.GetLength() != actual_array.GetLength())
      return false;
    for (uint32_t i = 0; i < expected_array.GetLength(); ++i) {
      if (!VarsEqual(expected_array.Get(i), actual_array.Get(i), visited_ids))
        return false;
    }
    return true;
  } else if (expected.is_dictionary()) {
    pp::VarDictionary expected_dict(expected);
    pp::VarDictionary actual_dict(actual);
    if (expected_dict.GetKeys().GetLength() !=
        actual_dict.GetKeys().GetLength()) {
      return false;
    }
    for (uint32_t i = 0; i < expected_dict.GetKeys().GetLength(); ++i) {
      pp::Var key = expected_dict.GetKeys().Get(i);
      if (!actual_dict.HasKey(key))
        return false;
      if (!VarsEqual(expected_dict.Get(key), actual_dict.Get(key), visited_ids))
        return false;
    }
    return true;
  } else {
    return expected == actual;
  }
}

bool VarsEqual(const pp::Var& expected,
               const pp::Var& actual) {
  std::map<int64_t, int64_t> visited_ids;
  return VarsEqual(expected, actual, &visited_ids);
}

class ScopedArrayBufferSizeSetter {
 public:
  ScopedArrayBufferSizeSetter(const PPB_Testing_Private* interface,
                              PP_Instance instance,
                              uint32_t threshold)
     : interface_(interface),
       instance_(instance) {
    interface_->SetMinimumArrayBufferSizeForShmem(instance_, threshold);
  }
  ~ScopedArrayBufferSizeSetter() {
    interface_->SetMinimumArrayBufferSizeForShmem(instance_, 0);
  }
 private:
  const PPB_Testing_Private* interface_;
  PP_Instance instance_;
};

#define FINISHED_WAITING_MESSAGE "TEST_POST_MESSAGE_FINISHED_WAITING"

}  // namespace

TestPostMessage::TestPostMessage(TestingInstance* instance)
    : TestCase(instance) {
}

TestPostMessage::~TestPostMessage() {
  instance_->PostMessage(pp::Var("This isn't guaranteed to be received, but "
                                 "shouldn't cause a crash."));

  // Remove the special listener that only responds to a FINISHED_WAITING
  // string. See Init for where it gets added.
  std::string js_code;
  js_code += "var plugin = document.getElementById('plugin');"
             "plugin.removeEventListener('message',"
             "                           plugin.wait_for_messages_handler);"
             "delete plugin.wait_for_messages_handler;";
  instance_->EvalScript(js_code);
}

bool TestPostMessage::Init() {
  bool success = CheckTestingInterface();

  // Set up a special listener that only responds to a FINISHED_WAITING string.
  // This is for use by WaitForMessages.
  std::string js_code;
  // Note the following code is dependent on some features of test_case.html.
  // E.g., it is assumed that the DOM element where the plugin is embedded has
  // an id of 'plugin', and there is a function 'IsTestingMessage' that allows
  // us to ignore the messages that are intended for use by the testing
  // framework itself.
  js_code += "var plugin = document.getElementById('plugin');"
             "var wait_for_messages_handler = function(message_event) {"
             "  if (!IsTestingMessage(message_event.data) &&"
             "      message_event.data === '" FINISHED_WAITING_MESSAGE "') {"
             "    plugin.postMessage('" FINISHED_WAITING_MESSAGE "');"
             "  }"
             "};"
             "plugin.addEventListener('message', wait_for_messages_handler);"
             // Stash it on the plugin so we can remove it in the destructor.
             "plugin.wait_for_messages_handler = wait_for_messages_handler;";
  instance_->EvalScript(js_code);

  // Set up the JavaScript message event listener to echo the data part of the
  // message event back to us.
  success = success && AddEchoingListener("message_event.data");
  message_data_.clear();
  // Send a message that the first test will expect to receive. This is to
  // verify that we can send messages when the 'Instance::Init' function is on
  // the stack.
  instance_->PostMessage(pp::Var(kTestString));

  return success;
}

void TestPostMessage::RunTests(const std::string& filter) {
  // Note: SendInInit must be first, because it expects to receive a message
  // that was sent in Init above.
  RUN_TEST(SendInInit, filter);
  RUN_TEST(SendingData, filter);
  RUN_TEST(SendingString, filter);
  RUN_TEST(SendingArrayBuffer, filter);
  RUN_TEST(SendingArray, filter);
  RUN_TEST(SendingDictionary, filter);
  RUN_TEST(SendingResource, filter);
  RUN_TEST(SendingComplexVar, filter);
  RUN_TEST(MessageEvent, filter);
  RUN_TEST(NoHandler, filter);
  RUN_TEST(ExtraParam, filter);
  if (testing_interface_->IsOutOfProcess())
    RUN_TEST(NonMainThread, filter);
}

void TestPostMessage::HandleMessage(const pp::Var& message_data) {
  if (message_data.is_string() &&
      (message_data.AsString() == FINISHED_WAITING_MESSAGE))
    testing_interface_->QuitMessageLoop(instance_->pp_instance());
  else
    message_data_.push_back(message_data);
}

bool TestPostMessage::AddEchoingListener(const std::string& expression) {
  std::string js_code;
  // Note the following code is dependent on some features of test_case.html.
  // E.g., it is assumed that the DOM element where the plugin is embedded has
  // an id of 'plugin', and there is a function 'IsTestingMessage' that allows
  // us to ignore the messages that are intended for use by the testing
  // framework itself.
  js_code += "var plugin = document.getElementById('plugin');"
             "var message_handler = function(message_event) {"
             "  if (!IsTestingMessage(message_event.data) &&"
             "      !(message_event.data === '" FINISHED_WAITING_MESSAGE "')) {"
             "    plugin.postMessage(";
  js_code += expression;
  js_code += "                      );"
             "  }"
             "};"
             "plugin.addEventListener('message', message_handler);"
             // Maintain an array of all event listeners, attached to the
             // plugin. This is so that we can easily remove them later (see
             // ClearListeners()).
             "if (!plugin.eventListeners) plugin.eventListeners = [];"
             "plugin.eventListeners.push(message_handler);";
  instance_->EvalScript(js_code);
  return true;
}

bool TestPostMessage::PostMessageFromJavaScript(const std::string& func) {
  std::string js_code;
  js_code += "var plugin = document.getElementById('plugin');"
             "plugin.postMessage(";
  js_code += func + "()";
  js_code += "                      );";
  instance_->EvalScript(js_code);
  return true;
}

bool TestPostMessage::ClearListeners() {
  std::string js_code;
  js_code += "var plugin = document.getElementById('plugin');"
             "while (plugin.eventListeners.length) {"
             "  plugin.removeEventListener('message',"
             "                             plugin.eventListeners.pop());"
             "}";
  instance_->EvalScript(js_code);
  return true;
}

int TestPostMessage::WaitForMessages() {
  size_t message_size_before = message_data_.size();
  // We first post a FINISHED_WAITING_MESSAGE. This should be guaranteed to
  // come back _after_ any other incoming messages that were already pending.
  instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE));
  testing_interface_->RunMessageLoop(instance_->pp_instance());
  // Now that the FINISHED_WAITING_MESSAGE has been echoed back to us, we know
  // that all pending messages have been slurped up. Return the number we
  // received (which may be zero).
  return message_data_.size() - message_size_before;
}

std::string TestPostMessage::CheckMessageProperties(
    const pp::Var& test_data,
    const std::vector<std::string>& properties_to_check) {
  typedef std::vector<std::string>::const_iterator Iterator;
  for (Iterator iter = properties_to_check.begin();
       iter != properties_to_check.end();
       ++iter) {
    ASSERT_TRUE(AddEchoingListener(*iter));
    message_data_.clear();
    instance_->PostMessage(test_data);
    ASSERT_EQ(0, message_data_.size());
    ASSERT_EQ(1, WaitForMessages());
    ASSERT_TRUE(message_data_.back().is_bool());
    if (!message_data_.back().AsBool())
      return std::string("Failed: ") + *iter;
    ASSERT_TRUE(message_data_.back().AsBool());
    ASSERT_TRUE(ClearListeners());
  }
  PASS();
}

std::string TestPostMessage::TestSendInInit() {
  // Wait for the messages from Init() to be guaranteed to be sent.
  WaitForMessages();
  // This test assumes Init already sent a message.
  ASSERT_EQ(1, message_data_.size());
  ASSERT_TRUE(message_data_.back().is_string());
  ASSERT_EQ(kTestString, message_data_.back().AsString());
  message_data_.clear();
  PASS();
}

std::string TestPostMessage::TestSendingData() {
  // Clean up after previous tests. This also swallows the message sent by Init
  // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
  // should start with these.
  WaitForMessages();
  ASSERT_TRUE(ClearListeners());

  // Set up the JavaScript message event listener to echo the data part of the
  // message event back to us.
  ASSERT_TRUE(AddEchoingListener("message_event.data"));

  // Test sending a message to JavaScript for each supported type. The JS sends
  // the data back to us, and we check that they match.
  message_data_.clear();
  instance_->PostMessage(pp::Var(kTestBool));
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_bool());
  ASSERT_EQ(message_data_.back().AsBool(), kTestBool);

  message_data_.clear();
  instance_->PostMessage(pp::Var(kTestInt));
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_number());
  ASSERT_DOUBLE_EQ(static_cast<double>(kTestInt),
                   message_data_.back().AsDouble());

  message_data_.clear();
  instance_->PostMessage(pp::Var(kTestDouble));
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_number());
  ASSERT_DOUBLE_EQ(message_data_.back().AsDouble(), kTestDouble);

  message_data_.clear();
  instance_->PostMessage(pp::Var());
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_undefined());

  message_data_.clear();
  instance_->PostMessage(pp::Var(pp::Var::Null()));
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_null());

  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  PASS();
}

std::string TestPostMessage::TestSendingString() {
  // Clean up after previous tests. This also swallows the message sent by Init
  // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
  // should start with these.
  WaitForMessages();
  ASSERT_TRUE(ClearListeners());

  // Test that a string var is converted to a primitive JS string.
  message_data_.clear();
  std::vector<std::string> properties_to_check;
  properties_to_check.push_back(
      "typeof message_event.data === 'string'");
  ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(kTestString,
                                                properties_to_check));

  ASSERT_TRUE(AddEchoingListener("message_event.data"));
  message_data_.clear();
  instance_->PostMessage(pp::Var(kTestString));
  // PostMessage is asynchronous, so we should not receive a response yet.
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_string());
  ASSERT_EQ(message_data_.back().AsString(), kTestString);

  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  PASS();
}

std::string TestPostMessage::TestSendingArrayBuffer() {
  // Clean up after previous tests. This also swallows the message sent by Init
  // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
  // should start with these.
  WaitForMessages();
  ASSERT_TRUE(ClearListeners());

  // TODO(sehr,dmichael): Add testing of longer array buffers when
  // crbug.com/110086 is fixed.
  ScopedArrayBufferSizeSetter setter(testing_interface_,
                                     instance_->pp_instance(),
                                     200);
  uint32_t sizes[] = { 0, 100, 1000, 10000 };
  for (size_t i = 0; i < sizeof(sizes)/sizeof(sizes[i]); ++i) {
    std::ostringstream size_stream;
    size_stream << sizes[i];
    const std::string kSizeAsString(size_stream.str());

    // Create an appropriately sized array buffer with test_data[i] == i.
    pp::VarArrayBuffer test_data(sizes[i]);
    if (sizes[i] > 0)
      ASSERT_NE(NULL, test_data.Map());
    // Make sure we can Unmap/Map successfully (there's not really any way to
    // detect if it's unmapped, so we just re-map before getting the pointer to
    // the buffer).
    test_data.Unmap();
    test_data.Map();
    ASSERT_EQ(sizes[i], test_data.ByteLength());
    unsigned char* buff = static_cast<unsigned char*>(test_data.Map());
    const uint32_t kByteLength = test_data.ByteLength();
    for (size_t j = 0; j < kByteLength; ++j)
      buff[j] = static_cast<uint8_t>(j % 256u);

    // Have the listener test some properties of the ArrayBuffer.
    std::vector<std::string> properties_to_check;
    properties_to_check.push_back(
        "message_event.data.constructor.name === 'ArrayBuffer'");
    properties_to_check.push_back(
        std::string("message_event.data.byteLength === ") + kSizeAsString);
    if (sizes[i] > 0) {
      properties_to_check.push_back(
          "(new DataView(message_event.data)).getUint8(0) == 0");
      // Checks that the last element has the right value: (byteLength-1)%256.
      std::string received_byte("(new DataView(message_event.data)).getUint8("
                                "    message_event.data.byteLength-1)");
      std::string expected_byte("(message_event.data.byteLength-1)%256");
      properties_to_check.push_back(received_byte + " == " + expected_byte);
    }
    ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(test_data,
                                                  properties_to_check));

    // Set up the JavaScript message event listener to echo the data part of the
    // message event back to us.
    ASSERT_TRUE(AddEchoingListener("message_event.data"));
    message_data_.clear();
    instance_->PostMessage(test_data);
    // PostMessage is asynchronous, so we should not receive a response yet.
    ASSERT_EQ(0, message_data_.size());
    ASSERT_EQ(1, WaitForMessages());
    ASSERT_TRUE(message_data_.back().is_array_buffer());
    pp::VarArrayBuffer received(message_data_.back());
    message_data_.clear();
    ASSERT_EQ(test_data.ByteLength(), received.ByteLength());
    unsigned char* received_buff = static_cast<unsigned char*>(received.Map());
    // The buffer should be copied, so this should be a distinct buffer. When
    // 'transferrables' are implemented for PPAPI, we'll also want to test that
    // we get the _same_ buffer back when it's transferred.
    if (sizes[i] > 0)
      ASSERT_NE(buff, received_buff);
    for (size_t i = 0; i < test_data.ByteLength(); ++i)
      ASSERT_EQ(buff[i], received_buff[i]);

    message_data_.clear();
    ASSERT_TRUE(ClearListeners());
  }

  PASS();
}

std::string TestPostMessage::TestSendingArray() {
  // Clean up after previous tests. This also swallows the message sent by Init
  // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
  // should start with these.
  WaitForMessages();
  ASSERT_TRUE(ClearListeners());

  pp::VarArray array;
  array.Set(0, pp::Var(kTestBool));
  array.Set(1, pp::Var(kTestString));
  // Purposely leave index 2 empty.
  array.Set(3, pp::Var(kTestInt));
  array.Set(4, pp::Var(kTestDouble));

  std::stringstream ss;
  ss << array.GetLength();
  std::string length_as_string(ss.str());

  // Have the listener test some properties of the Array.
  std::vector<std::string> properties_to_check;
  properties_to_check.push_back(
      "message_event.data.constructor.name === 'Array'");
  properties_to_check.push_back(
      std::string("message_event.data.length === ") + length_as_string);
  // Check that the string is converted to a primitive JS string.
  properties_to_check.push_back(
      std::string("typeof message_event.data[1] === 'string'"));
  ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(array, properties_to_check));

  // Set up the JavaScript message event listener to echo the data part of the
  // message event back to us.
  ASSERT_TRUE(AddEchoingListener("message_event.data"));
  message_data_.clear();
  instance_->PostMessage(array);
  // PostMessage is asynchronous, so we should not receive a response yet.
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_array());
  ASSERT_TRUE(VarsEqual(array, message_data_.back()));

  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  PASS();
}

std::string TestPostMessage::TestSendingDictionary() {
  // Clean up after previous tests. This also swallows the message sent by Init
  // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
  // should start with these.
  WaitForMessages();
  ASSERT_TRUE(ClearListeners());

  pp::VarDictionary dictionary;
  dictionary.Set(pp::Var("foo"), pp::Var(kTestBool));
  dictionary.Set(pp::Var("bar"), pp::Var(kTestString));
  dictionary.Set(pp::Var("abc"), pp::Var(kTestInt));
  dictionary.Set(pp::Var("def"), pp::Var());

  std::stringstream ss;
  ss << dictionary.GetKeys().GetLength();
  std::string length_as_string(ss.str());

  // Have the listener test some properties of the Dictionary.
  std::vector<std::string> properties_to_check;
  properties_to_check.push_back(
      "message_event.data.constructor.name === 'Object'");
  properties_to_check.push_back(
      std::string("Object.keys(message_event.data).length === ") +
      length_as_string);
  // Check that the string is converted to a primitive JS string.
  properties_to_check.push_back(
      std::string("typeof message_event.data['bar'] === 'string'"));
  ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(dictionary,
                                                properties_to_check));

  // Set up the JavaScript message event listener to echo the data part of the
  // message event back to us.
  ASSERT_TRUE(AddEchoingListener("message_event.data"));
  message_data_.clear();
  instance_->PostMessage(dictionary);
  // PostMessage is asynchronous, so we should not receive a response yet.
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_dictionary());
  ASSERT_TRUE(VarsEqual(dictionary, message_data_.back()));

  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  PASS();
}

std::string TestPostMessage::TestSendingResource() {
  // Clean up after previous tests. This also swallows the message sent by Init
  // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
  // should start with these.
  WaitForMessages();
  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  std::string file_path("/");
  file_path += kTestFilename;
  int content_length = strlen(kTestString);

  // Create a file in the HTML5 temporary file system, in the Pepper plugin.
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  pp::FileRef write_file_ref(file_system, file_path.c_str());
  // Write to the file.
  pp::FileIO write_file_io(instance_);
  ASSERT_NE(0, write_file_io.pp_resource());
  callback.WaitForResult(
      write_file_io.Open(write_file_ref,
                         PP_FILEOPENFLAG_WRITE | PP_FILEOPENFLAG_CREATE,
                         callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  callback.WaitForResult(write_file_io.Write(
      0, kTestString, content_length, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(callback.result(), content_length);
  write_file_io.Close();

  // Pass the file system to JavaScript and have the listener test some
  // properties of the file system.
  pp::Var file_system_var(file_system);
  std::vector<std::string> properties_to_check;
  properties_to_check.push_back(
      "message_event.data.constructor.name === 'DOMFileSystem'");
  properties_to_check.push_back(
      "message_event.data.root.constructor.name === 'DirectoryEntry'");
  properties_to_check.push_back(
      "message_event.data.name.indexOf("
      "    ':Temporary',"
      "    message_event.data.name.length - ':Temporary'.length) !== -1");
  ASSERT_SUBTEST_SUCCESS(CheckMessageProperties(file_system_var,
                                                properties_to_check));

  // Set up the JavaScript message event listener to echo the data part of the
  // message event back to us.
  ASSERT_TRUE(AddEchoingListener("message_event.data"));
  // Send the file system in a message from the Pepper plugin to JavaScript.
  message_data_.clear();
  instance_->PostMessage(file_system_var);
  // PostMessage is asynchronous, so we should not receive a response yet.
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());

  // The JavaScript should have posted the file system back to us. Verify that
  // it is a file system and read the file contents that we wrote earlier.
  pp::Var var = message_data_.back();
  ASSERT_TRUE(var.is_resource());
  pp::Resource result = var.AsResource();
  ASSERT_TRUE(pp::FileSystem::IsFileSystem(result));
  {
    pp::FileSystem received_file_system(result);
    pp::FileRef file_ref(received_file_system, file_path.c_str());
    ASSERT_NE(0, file_ref.pp_resource());

    // Ensure that the file can be queried.
    TestCompletionCallbackWithOutput<PP_FileInfo> cc(instance_->pp_instance(),
                                                     callback_type());
    cc.WaitForResult(file_ref.Query(cc.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(cc);
    ASSERT_EQ(PP_OK, cc.result());
    ASSERT_EQ(cc.output().size, content_length);

    // Read the file and test that its contents match.
    pp::FileIO file_io(instance_);
    ASSERT_NE(0, file_io.pp_resource());
    callback.WaitForResult(
        file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(PP_OK, callback.result());

    std::vector<char> buffer_vector(content_length);
    char* buffer = &buffer_vector[0];  // Note: Not null-terminated!
    callback.WaitForResult(
        file_io.Read(0, buffer, content_length, callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(callback.result(), content_length);
    ASSERT_EQ(0, memcmp(buffer, kTestString, content_length));
  }

  WaitForMessages();
  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  PASS();
}

std::string TestPostMessage::TestSendingComplexVar() {
  // Clean up after previous tests. This also swallows the message sent by Init
  // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit'
  // should start with these.
  WaitForMessages();
  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  pp::Var string(kTestString);
  pp::VarDictionary dictionary;
  dictionary.Set(pp::Var("foo"), pp::Var(kTestBool));
  dictionary.Set(pp::Var("bar"), string);
  dictionary.Set(pp::Var("abc"), pp::Var(kTestInt));
  dictionary.Set(pp::Var("def"), pp::Var());

  // Reference to array.
  pp::VarArray array;
  array.Set(0, pp::Var(kTestBool));
  array.Set(1, string);
  // Purposely leave index 2 empty (which will place an undefined var there).
  array.Set(3, pp::Var(kTestInt));
  array.Set(4, pp::Var(kTestDouble));

  dictionary.Set(pp::Var("array-ref1"), array);
  dictionary.Set(pp::Var("array-ref2"), array);

  // Set up the JavaScript message event listener to echo the data part of the
  // message event back to us.
  ASSERT_TRUE(AddEchoingListener("message_event.data"));
  instance_->PostMessage(dictionary);
  // PostMessage is asynchronous, so we should not receive a response yet.
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_dictionary());
  pp::VarDictionary result(message_data_.back());
  ASSERT_TRUE(VarsEqual(dictionary, message_data_.back()));

  WaitForMessages();
  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  // Set up a (dictionary -> array -> dictionary) cycle. Cycles shouldn't be
  // transmitted.
  pp::VarArray array2;
  array2.Set(0, dictionary);
  dictionary.Set(pp::Var("array2"), array2);

  ASSERT_TRUE(AddEchoingListener("message_event.data"));
  instance_->PostMessage(dictionary);
  // PostMessage is asynchronous, so we should not receive a response yet.
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(WaitForMessages(), 0);

  // Break the cycles.
  dictionary.Delete(pp::Var("array2"));

  WaitForMessages();
  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  // Test sending a cycle from JavaScript to the plugin.
  ASSERT_TRUE(AddEchoingListener("message_event.data"));
  PostMessageFromJavaScript("function() { var x = []; x[0] = x; return x; }");
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(WaitForMessages(), 0);

  WaitForMessages();
  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  PASS();
}

std::string TestPostMessage::TestMessageEvent() {
  // Set up the JavaScript message event listener to pass us some values from
  // the MessageEvent and make sure they match our expectations.

  WaitForMessages();
  ASSERT_TRUE(ClearListeners());
  // Have the listener pass back the class name of message_event and make sure
  // it's "MessageEvent".
  ASSERT_TRUE(AddEchoingListener("message_event.constructor.name"));
  message_data_.clear();
  instance_->PostMessage(pp::Var(kTestInt));
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_string());
  ASSERT_EQ(message_data_.back().AsString(), "MessageEvent");
  ASSERT_TRUE(ClearListeners());

  // Make sure all the non-data properties have the expected values.
  bool success = AddEchoingListener("((message_event.origin === '')"
                                   " && (message_event.lastEventId === '')"
                                   " && (message_event.source === null)"
                                   " && (message_event.ports.length === 0)"
                                   " && (message_event.bubbles === false)"
                                   " && (message_event.cancelable === false)"
                                   ")");
  ASSERT_TRUE(success);
  message_data_.clear();
  instance_->PostMessage(pp::Var(kTestInt));
  ASSERT_EQ(0, message_data_.size());
  ASSERT_EQ(1, WaitForMessages());
  ASSERT_TRUE(message_data_.back().is_bool());
  ASSERT_TRUE(message_data_.back().AsBool());
  ASSERT_TRUE(ClearListeners());

  // Add some event handlers to make sure they receive messages.
  ASSERT_TRUE(AddEchoingListener("1"));
  ASSERT_TRUE(AddEchoingListener("2"));
  ASSERT_TRUE(AddEchoingListener("3"));

  message_data_.clear();
  instance_->PostMessage(pp::Var(kTestInt));
  // Make sure we don't get a response in a re-entrant fashion.
  ASSERT_EQ(0, message_data_.size());
  // We should get 3 messages.
  ASSERT_EQ(WaitForMessages(), 3);
  // Copy to a vector of doubles and sort; w3c does not specify the order for
  // event listeners. (Copying is easier than writing an operator< for pp::Var.)
  //
  // See http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html.
  VarVector::iterator iter(message_data_.begin()), the_end(message_data_.end());
  std::vector<double> double_vec;
  for (; iter != the_end; ++iter) {
    ASSERT_TRUE(iter->is_number());
    double_vec.push_back(iter->AsDouble());
  }
  std::sort(double_vec.begin(), double_vec.end());
  ASSERT_DOUBLE_EQ(double_vec[0], 1.0);
  ASSERT_DOUBLE_EQ(double_vec[1], 2.0);
  ASSERT_DOUBLE_EQ(double_vec[2], 3.0);

  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  PASS();
}

std::string TestPostMessage::TestNoHandler() {
  // Delete any lingering messages and event listeners.
  WaitForMessages();
  ASSERT_TRUE(ClearListeners());

  // Now send a message.  We shouldn't get a response.
  message_data_.clear();
  instance_->PostMessage(pp::Var());
  ASSERT_EQ(WaitForMessages(), 0);
  ASSERT_TRUE(message_data_.empty());

  PASS();
}

std::string TestPostMessage::TestExtraParam() {
  // Delete any lingering messages and event listeners.
  WaitForMessages();
  ASSERT_TRUE(ClearListeners());
  // Add a listener that will respond with 1 and an empty array (where the
  // message port array would appear if it was Worker postMessage).
  ASSERT_TRUE(AddEchoingListener("1, []"));

  // Now send a message.  We shouldn't get a response.
  message_data_.clear();
  instance_->PostMessage(pp::Var());
  ASSERT_EQ(WaitForMessages(), 0);
  ASSERT_TRUE(message_data_.empty());

  ASSERT_TRUE(ClearListeners());

  PASS();
}

std::string TestPostMessage::TestNonMainThread() {
  WaitForMessages();
  ASSERT_TRUE(ClearListeners());
  ASSERT_TRUE(AddEchoingListener("message_event.data"));
  message_data_.clear();

  // Set up a thread for each integer from 0 to (kThreadsToRun - 1).  Make each
  // thread send the number that matches its index kMessagesToSendPerThread
  // times.  For good measure, call postMessage from the main thread
  // kMessagesToSendPerThread times. At the end, we make sure we got all the
  // values we expected.
  PP_ThreadType threads[kThreadsToRun];
  for (int32_t i = 0; i < kThreadsToRun; ++i) {
    // Set up a thread to send a value of i.
    void* arg = new InvokePostMessageThreadArg(instance_, pp::Var(i));
    PP_CreateThread(&threads[i], &InvokePostMessageThreadFunc, arg);
  }
  // Invoke PostMessage right now to send a value of (kThreadsToRun).
  for (int32_t i = 0; i < kMessagesToSendPerThread; ++i)
    instance_->PostMessage(pp::Var(kThreadsToRun));

  // Now join all threads.
  for (int32_t i = 0; i < kThreadsToRun; ++i)
    PP_JoinThread(threads[i]);

  // PostMessage is asynchronous, so we should not receive a response yet.
  ASSERT_EQ(0, message_data_.size());

  // Make sure we got all values that we expected.  Note that because it's legal
  // for the JavaScript engine to treat our integers as floating points, we
  // can't just use std::find or equality comparison. So we instead, we convert
  // each incoming value to an integer, and count them in received_counts.
  int32_t expected_num = (kThreadsToRun + 1) * kMessagesToSendPerThread;
  // Count how many we receive per-index.
  std::vector<int32_t> expected_counts(kThreadsToRun + 1,
                                       kMessagesToSendPerThread);
  std::vector<int32_t> received_counts(kThreadsToRun + 1, 0);
  ASSERT_EQ(expected_num, WaitForMessages());
  for (int32_t i = 0; i < expected_num; ++i) {
    const pp::Var& latest_var(message_data_[i]);
    ASSERT_TRUE(latest_var.is_int() || latest_var.is_double());
    int32_t received_value = -1;
    if (latest_var.is_int()) {
      received_value = latest_var.AsInt();
    } else if (latest_var.is_double()) {
      received_value = static_cast<int32_t>(latest_var.AsDouble() + 0.5);
    }
    ASSERT_TRUE(received_value >= 0);
    ASSERT_TRUE(received_value <= kThreadsToRun);
    ++received_counts[received_value];
  }
  ASSERT_EQ(expected_counts, received_counts);

  message_data_.clear();
  ASSERT_TRUE(ClearListeners());

  PASS();
}
