// 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 <stddef.h>
#include <stdint.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);
}

#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();

  // Add a post condition to tests which caches the postMessage function and
  // then calls it after the instance is destroyed. The ensures that no UAF
  // occurs because the MessageChannel may still be alive after the plugin
  // instance is destroyed (it will get garbage collected eventually).
  instance_->EvalScript("window.pluginPostMessage = "
                        "document.getElementById('plugin').postMessage");
  instance_->AddPostCondition("window.pluginPostMessage('') === undefined");

  // 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 static_cast<int>(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 = static_cast<int>(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_Thread 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();
}
