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

#include "ppapi/proxy/serialized_var.h"
#include "ppapi/shared_impl/proxy_lock.h"

namespace ppapi {
namespace proxy {

namespace {

PP_Var MakeObjectVar(int64_t object_id) {
  PP_Var ret;
  ret.type = PP_VARTYPE_OBJECT;
  ret.value.as_id = object_id;
  return ret;
}

class SerializedVarTest : public PluginProxyTest {
 public:
  SerializedVarTest() {}
};

}  // namespace

// Tests output arguments in the plugin. This is when the host calls into the
// plugin and the plugin returns something via an out param, like an exception.
TEST_F(SerializedVarTest, PluginSerializedVarInOutParam) {
  ProxyAutoLock lock;
  PP_Var host_object = MakeObjectVar(0x31337);

  PP_Var plugin_object;
  {
    // Receive the object param, we should be tracking it with no refcount, and
    // no messages sent.
    SerializedVarTestConstructor input(host_object);
    SerializedVarReceiveInput receive_input(input);
    plugin_object = receive_input.Get(plugin_dispatcher());
    EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(0u, sink().message_count());

    SerializedVar sv;
    {
      // The "OutParam" does its work in its destructor, it will write the
      // information to the SerializedVar we passed in the constructor.
      SerializedVarOutParam out_param(&sv);
      // An out-param needs to pass a reference to the caller, so it's the
      // responsibility of the plugin to bump the ref-count on an input
      // parameter.
      var_tracker().AddRefVar(plugin_object);
      EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
      // We should have informed the host that a reference was taken.
      EXPECT_EQ(1u, sink().message_count());
      *out_param.OutParam(plugin_dispatcher()) = plugin_object;
    }

    // The object should have transformed the plugin object back to the host
    // object ID. Nothing in the var tracker should have changed yet, and no
    // messages should have been sent.
    SerializedVarTestReader reader(sv);
    EXPECT_EQ(host_object.value.as_id, reader.GetVar().value.as_id);
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(1u, sink().message_count());
  }

  // The out param should have done an "end receive caller owned" on the plugin
  // var serialization rules, which should have released the "track-with-no-
  // reference" count in the var tracker as well as the 1 reference we passed
  // back to the host, so the object should no longer be in the tracker. The
  // reference we added has been removed, so another message should be sent to
  // the host to tell it we're done with the object.
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object));
  EXPECT_EQ(2u, sink().message_count());
}

// Tests output strings in the plugin. This is when the host calls into the
// plugin with a string and the plugin returns it via an out param.
TEST_F(SerializedVarTest, PluginSerializedStringVarInOutParam) {
  ProxyAutoLock lock;
  PP_Var plugin_string;
  const std::string kTestString("elite");
  {
    // Receive the string param. We should track it with 1 refcount.
    SerializedVarTestConstructor input(kTestString);
    SerializedVarReceiveInput receive_input(input);
    plugin_string = receive_input.Get(plugin_dispatcher());
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_string));
    EXPECT_EQ(0u, sink().message_count());

    SerializedVar sv;
    {
      // The "OutParam" does its work in its destructor, it will write the
      // information to the SerializedVar we passed in the constructor.
      SerializedVarOutParam out_param(&sv);
      // An out-param needs to pass a reference to the caller, so it's the
      // responsibility of the plugin to bump the ref-count of an input
      // parameter.
      var_tracker().AddRefVar(plugin_string);
      EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_string));
      EXPECT_EQ(0u, sink().message_count());
      *out_param.OutParam(plugin_dispatcher()) = plugin_string;
    }

    // The SerializedVar should have set the string value internally. Nothing in
    // the var tracker should have changed yet, and no messages should have been
    // sent.
    SerializedVarTestReader reader(sv);
    //EXPECT_EQ(kTestString, *reader.GetTrackerStringPtr());
    EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_string));
    EXPECT_EQ(0u, sink().message_count());
  }
  // The reference the string had initially should be gone, and the reference we
  // passed to the host should also be gone, so the string should be removed.
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_string));
  EXPECT_EQ(0u, sink().message_count());
}

// Tests receiving an argument and passing it back to the browser as an output
// parameter.
TEST_F(SerializedVarTest, PluginSerializedVarOutParam) {
  ProxyAutoLock lock;
  PP_Var host_object = MakeObjectVar(0x31337);

  // Start tracking this object in the plugin.
  PP_Var plugin_object = var_tracker().ReceiveObjectPassRef(
      host_object, plugin_dispatcher());
  EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));

  {
    SerializedVar sv;
    {
      // The "OutParam" does its work in its destructor, it will write the
      // information to the SerializedVar we passed in the constructor.
      SerializedVarOutParam out_param(&sv);
      *out_param.OutParam(plugin_dispatcher()) = plugin_object;
    }

    // The object should have transformed the plugin object back to the host
    // object ID. Nothing in the var tracker should have changed yet, and no
    // messages should have been sent.
    SerializedVarTestReader reader(sv);
    EXPECT_EQ(host_object.value.as_id, reader.GetVar().value.as_id);
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(0u, sink().message_count());
  }

  // The out param should have done an "end send pass ref" on the plugin
  // var serialization rules, which should have in turn released the reference
  // in the var tracker. Since we only had one reference, this should have sent
  // a release to the browser.
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object));
  EXPECT_EQ(1u, sink().message_count());

  // We don't bother validating that message since it's nontrivial and the
  // PluginVarTracker test has cases that cover that this message is correct.
}

// Tests the case that the plugin receives the same var twice as an input
// parameter (not passing ownership).
TEST_F(SerializedVarTest, PluginReceiveInput) {
  ProxyAutoLock lock;
  PP_Var host_object = MakeObjectVar(0x31337);

  PP_Var plugin_object;
  {
    // Receive the first param, we should be tracking it with no refcount, and
    // no messages sent.
    SerializedVarTestConstructor input1(host_object);
    SerializedVarReceiveInput receive_input(input1);
    plugin_object = receive_input.Get(plugin_dispatcher());
    EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(0u, sink().message_count());

    // Receive the second param, it should be resolved to the same plugin
    // object and there should still be no refcount.
    SerializedVarTestConstructor input2(host_object);
    SerializedVarReceiveInput receive_input2(input2);
    PP_Var plugin_object2 = receive_input2.Get(plugin_dispatcher());
    EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id);
    EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(0u, sink().message_count());

    // Take a reference to the object, as if the plugin was using it, and then
    // release it, we should still be tracking the object since the
    // ReceiveInputs keep the "track_with_no_reference_count" alive until
    // they're destroyed.
    var_tracker().AddRefVar(plugin_object);
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
    var_tracker().ReleaseVar(plugin_object);
    EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(2u, sink().message_count());
  }

  // Since we didn't keep any refs to the objects, it should have freed the
  // object.
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object));
}

// Tests the case that the plugin receives the same vars twice as an input
// parameter (not passing ownership) within a vector.
TEST_F(SerializedVarTest, PluginVectorReceiveInput) {
  ProxyAutoLock lock;
  PP_Var host_object = MakeObjectVar(0x31337);

  std::vector<PP_Var> plugin_objects;
  std::vector<PP_Var> plugin_objects2;
  {
    // Receive the params. The object should be tracked with no refcount and
    // no messages sent. The string should is plugin-side only and should have
    // a reference-count of 1.
    std::vector<SerializedVar> input1;
    input1.push_back(SerializedVarTestConstructor(host_object));
    input1.push_back(SerializedVarTestConstructor("elite"));
    SerializedVarVectorReceiveInput receive_input(input1);
    uint32_t array_size = 0;
    PP_Var* plugin_objects_array =
        receive_input.Get(plugin_dispatcher(), &array_size);
    plugin_objects.insert(plugin_objects.begin(), plugin_objects_array,
                          plugin_objects_array + array_size);
    ASSERT_EQ(2u, array_size);
    EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0]));
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[1]));
    EXPECT_EQ(0u, sink().message_count());

    // Receive the second param, it should be resolved to the same plugin
    // object and there should still be no refcount.
    std::vector<SerializedVar> input2;
    input2.push_back(SerializedVarTestConstructor(host_object));
    input2.push_back(SerializedVarTestConstructor("elite"));
    SerializedVarVectorReceiveInput receive_input2(input2);
    uint32_t array_size2 = 0;
    PP_Var* plugin_objects_array2 =
        receive_input2.Get(plugin_dispatcher(), &array_size2);
    plugin_objects2.insert(plugin_objects2.begin(), plugin_objects_array2,
                           plugin_objects_array2 + array_size2);
    ASSERT_EQ(2u, array_size2);
    EXPECT_EQ(plugin_objects[0].value.as_id, plugin_objects2[0].value.as_id);
    EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0]));
    // Strings get re-created with a new ID. We don't try to reuse strings in
    // the tracker, so the string should get a new ID.
    EXPECT_NE(plugin_objects[1].value.as_id, plugin_objects2[1].value.as_id);
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects2[1]));
    EXPECT_EQ(0u, sink().message_count());

    // Take a reference to the object, as if the plugin was using it, and then
    // release it, we should still be tracking the object since the
    // ReceiveInputs keep the "track_with_no_reference_count" alive until
    // they're destroyed.
    var_tracker().AddRefVar(plugin_objects[0]);
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[0]));
    var_tracker().ReleaseVar(plugin_objects[0]);
    EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_objects[0]));
    EXPECT_EQ(2u, sink().message_count());

    // Take a reference to a string and then release it. Make sure no messages
    // are sent.
    uint32_t old_message_count = sink().message_count();
    var_tracker().AddRefVar(plugin_objects[1]);
    EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_objects[1]));
    var_tracker().ReleaseVar(plugin_objects[1]);
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_objects[1]));
    EXPECT_EQ(old_message_count, sink().message_count());
  }

  // Since we didn't keep any refs to the objects or strings, so they should
  // have been freed.
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects[0]));
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects[1]));
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_objects2[1]));
}

// Tests the plugin receiving a var as a return value from the browser
// two different times (passing ownership).
TEST_F(SerializedVarTest, PluginReceiveReturn) {
  ProxyAutoLock lock;
  PP_Var host_object = MakeObjectVar(0x31337);

  PP_Var plugin_object;
  {
    // Receive the first param, we should be tracking it with a refcount of 1.
    SerializedVarTestConstructor input1(host_object);
    ReceiveSerializedVarReturnValue receive_input(input1);
    plugin_object = receive_input.Return(plugin_dispatcher());
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(0u, sink().message_count());

    // Receive the second param, it should be resolved to the same plugin
    // object and there should be a plugin refcount of 2. There should have
    // been an IPC message sent that released the duplicated ref in the browser
    // (so both of our refs are represented by one in the browser).
    SerializedVarTestConstructor input2(host_object);
    ReceiveSerializedVarReturnValue receive_input2(input2);
    PP_Var plugin_object2 = receive_input2.Return(plugin_dispatcher());
    EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id);
    EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(1u, sink().message_count());
  }

  // The ReceiveSerializedVarReturnValue destructor shouldn't have affected
  // the refcount or sent any messages.
  EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object));
  EXPECT_EQ(1u, sink().message_count());

  // Manually release one refcount, it shouldn't have sent any more messages.
  var_tracker().ReleaseVar(plugin_object);
  EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
  EXPECT_EQ(1u, sink().message_count());

  // Manually release the last refcount, it should have freed it and sent a
  // release message to the browser.
  var_tracker().ReleaseVar(plugin_object);
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object));
  EXPECT_EQ(2u, sink().message_count());
}

// Returns a value from the browser to the plugin, then return that one ref
// back to the browser.
TEST_F(SerializedVarTest, PluginReturnValue) {
  ProxyAutoLock lock;
  PP_Var host_object = MakeObjectVar(0x31337);

  PP_Var plugin_object;
  {
    // Receive the param in the plugin.
    SerializedVarTestConstructor input1(host_object);
    ReceiveSerializedVarReturnValue receive_input(input1);
    plugin_object = receive_input.Return(plugin_dispatcher());
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
    EXPECT_EQ(0u, sink().message_count());
  }

  {
    // Now return to the browser.
    SerializedVar output;
    SerializedVarReturnValue return_output(&output);
    return_output.Return(plugin_dispatcher(), plugin_object);

    // The ref in the plugin should be alive until the ReturnValue goes out of
    // scope, since the release needs to be after the browser processes the
    // message.
    EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object));
  }

  // When the ReturnValue object goes out of scope, it should have sent a
  // release message to the browser.
  EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object));
  EXPECT_EQ(1u, sink().message_count());
}

}  // namespace proxy
}  // namespace ppapi
