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

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/shared_impl/array_var.h"
#include "ppapi/shared_impl/dictionary_var.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource_var.h"
#include "ppapi/shared_impl/scoped_pp_var.h"
#include "ppapi/shared_impl/test_globals.h"
#include "ppapi/shared_impl/unittest_utils.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/shared_impl/var_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ppapi {
namespace proxy {

namespace {

void DefaultHandleWriter(IPC::Message* m, const SerializedHandle& handle) {
  IPC::ParamTraits<SerializedHandle>::Write(m, handle);
}

class RawVarDataTest : public testing::Test {
 public:
  RawVarDataTest() {}
  ~RawVarDataTest() {}

  // testing::Test implementation.
  virtual void SetUp() {
    ProxyLock::EnableLockingOnThreadForTest();
    ProxyLock::Acquire();
  }
  virtual void TearDown() {
    ASSERT_TRUE(PpapiGlobals::Get()->GetVarTracker()->GetLiveVars().empty());
    ProxyLock::Release();
  }

 private:
  TestGlobals globals_;
};

bool WriteAndRead(const PP_Var& var, PP_Var* result) {
  PP_Instance dummy_instance = 1234;
  scoped_ptr<RawVarDataGraph> expected_data(RawVarDataGraph::Create(
      var, dummy_instance));
  if (!expected_data)
    return false;
  IPC::Message m;
  expected_data->Write(&m, base::Bind(&DefaultHandleWriter));
  PickleIterator iter(m);
  scoped_ptr<RawVarDataGraph> actual_data(RawVarDataGraph::Read(&m, &iter));
  *result = actual_data->CreatePPVar(dummy_instance);
  return true;
}

// Assumes a ref for var.
bool WriteReadAndCompare(const PP_Var& var) {
  ScopedPPVar expected(ScopedPPVar::PassRef(), var);
  PP_Var result;
  bool success = WriteAndRead(expected.get(), &result);
  if (!success)
    return false;
  ScopedPPVar actual(ScopedPPVar::PassRef(), result);
  return TestEqual(expected.get(), actual.get(), true);
}

}  // namespace

TEST_F(RawVarDataTest, SimpleTest) {
  EXPECT_TRUE(WriteReadAndCompare(PP_MakeUndefined()));
  EXPECT_TRUE(WriteReadAndCompare(PP_MakeNull()));
  EXPECT_TRUE(WriteReadAndCompare(PP_MakeInt32(100)));
  EXPECT_TRUE(WriteReadAndCompare(PP_MakeBool(PP_TRUE)));
  EXPECT_TRUE(WriteReadAndCompare(PP_MakeDouble(53.75)));
  PP_Var object;
  object.type = PP_VARTYPE_OBJECT;
  object.value.as_id = 10;
  EXPECT_TRUE(WriteReadAndCompare(object));
}

TEST_F(RawVarDataTest, StringTest) {
  EXPECT_TRUE(WriteReadAndCompare(StringVar::StringToPPVar("")));
  EXPECT_TRUE(WriteReadAndCompare(StringVar::StringToPPVar("hello world!")));
}

TEST_F(RawVarDataTest, ArrayBufferTest) {
  std::string data = "hello world!";
  PP_Var var = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
      data.size(), data.data());
  EXPECT_TRUE(WriteReadAndCompare(var));
  var = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
      0, static_cast<void*>(NULL));
  EXPECT_TRUE(WriteReadAndCompare(var));
  // TODO(raymes): add tests for shmem type array buffers.
}

TEST_F(RawVarDataTest, DictionaryArrayTest) {
  // Empty array.
  scoped_refptr<ArrayVar> array(new ArrayVar);
  ScopedPPVar release_array(ScopedPPVar::PassRef(), array->GetPPVar());
  EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar()));

  size_t index = 0;

  // Array with primitives.
  array->Set(index++, PP_MakeUndefined());
  array->Set(index++, PP_MakeNull());
  array->Set(index++, PP_MakeInt32(100));
  array->Set(index++, PP_MakeBool(PP_FALSE));
  array->Set(index++, PP_MakeDouble(0.123));
  EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar()));

  // Array with 2 references to the same string.
  ScopedPPVar release_string(
      ScopedPPVar::PassRef(), StringVar::StringToPPVar("abc"));
  array->Set(index++, release_string.get());
  array->Set(index++, release_string.get());
  EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar()));

  // Array with nested array that references the same string.
  scoped_refptr<ArrayVar> array2(new ArrayVar);
  ScopedPPVar release_array2(ScopedPPVar::PassRef(), array2->GetPPVar());
  array2->Set(0, release_string.get());
  array->Set(index++, release_array2.get());
  EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar()));

  // Empty dictionary.
  scoped_refptr<DictionaryVar> dictionary(new DictionaryVar);
  ScopedPPVar release_dictionary(ScopedPPVar::PassRef(),
                                 dictionary->GetPPVar());
  EXPECT_TRUE(WriteReadAndCompare(dictionary->GetPPVar()));

  // Dictionary with primitives.
  dictionary->SetWithStringKey("1", PP_MakeUndefined());
  dictionary->SetWithStringKey("2", PP_MakeNull());
  dictionary->SetWithStringKey("3", PP_MakeInt32(-100));
  dictionary->SetWithStringKey("4", PP_MakeBool(PP_TRUE));
  dictionary->SetWithStringKey("5", PP_MakeDouble(-103.52));
  EXPECT_TRUE(WriteReadAndCompare(dictionary->GetPPVar()));

  // Dictionary with 2 references to the same string.
  dictionary->SetWithStringKey("6", release_string.get());
  dictionary->SetWithStringKey("7", release_string.get());
  EXPECT_TRUE(WriteReadAndCompare(dictionary->GetPPVar()));

  // Dictionary with nested dictionary that references the same string.
  scoped_refptr<DictionaryVar> dictionary2(new DictionaryVar);
  ScopedPPVar release_dictionary2(ScopedPPVar::PassRef(),
                                  dictionary2->GetPPVar());
  dictionary2->SetWithStringKey("abc", release_string.get());
  dictionary->SetWithStringKey("8", release_dictionary2.get());
  EXPECT_TRUE(WriteReadAndCompare(dictionary->GetPPVar()));

  // Array with dictionary.
  array->Set(index++, release_dictionary.get());
  EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar()));

  // Array with dictionary with array.
  array2->Set(0, PP_MakeInt32(100));
  dictionary->SetWithStringKey("9", release_array2.get());
  EXPECT_TRUE(WriteReadAndCompare(array->GetPPVar()));

  // Array <-> dictionary cycle.
  dictionary->SetWithStringKey("10", release_array.get());
  PP_Var result;
  ASSERT_FALSE(WriteAndRead(release_dictionary.get(), &result));
  // Break the cycle.
  // TODO(raymes): We need some better machinery for releasing vars with
  // cycles. Remove the code below once we have that.
  dictionary->DeleteWithStringKey("10");

  // Array with self references.
  array->Set(index, release_array.get());
  ASSERT_FALSE(WriteAndRead(release_array.get(), &result));
  // Break the self reference.
  array->Set(index, PP_MakeUndefined());
}

TEST_F(RawVarDataTest, ResourceTest) {
  // TODO(mgiuca): This test passes trivially, since GetVarTracker() returns a
  // TestVarTracker which returns a null PP_Var.
  ScopedPPVar resource(
      ScopedPPVar::PassRef(),
      PpapiGlobals::Get()->GetVarTracker()->MakeResourcePPVar(34));
  EXPECT_TRUE(WriteReadAndCompare(resource.get()));

  // TODO(mgiuca): Test a host resource with an IPC::Message. It is currently a
  // checkfail to deserialize such a resource.
}

}  // namespace proxy
}  // namespace ppapi
