// Copyright (c) 2011 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 "testing/gtest/include/gtest/gtest.h"

#include "base/compiler_specific.h"
#include "base/test/task_environment.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/test_globals.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/shared_impl/var_tracker.h"

namespace ppapi {

namespace {

int mock_var_alive_count = 0;

class MockStringVar : public StringVar {
 public:
  MockStringVar(const std::string& str) : StringVar(str) {
    mock_var_alive_count++;
  }
  ~MockStringVar() override { mock_var_alive_count--; }
  bool HasValidVarID() { return GetExistingVarID() != 0; }
};

class MockObjectVar : public Var {
 public:
  MockObjectVar() : Var() { mock_var_alive_count++; }
  ~MockObjectVar() override { mock_var_alive_count--; }
  PP_VarType GetType() const override { return PP_VARTYPE_OBJECT; }
  bool HasValidVarID() { return GetExistingVarID() != 0; }
};

}  // namespace

class VarTrackerTest : public testing::Test {
 public:
  VarTrackerTest() {}

  // Test implementation.
  void SetUp() override {
    ASSERT_EQ(0, mock_var_alive_count);
  }
  void TearDown() override {}

  VarTracker& var_tracker() { return *globals_.GetVarTracker(); }

 private:
  base::test::SingleThreadTaskEnvironment
      task_environment_;  // Required to receive callbacks.
  TestGlobals globals_;
};

// Test that ResetVarID is called when the last PP_Var ref was deleted but the
// object lives on.
TEST_F(VarTrackerTest, LastResourceRef) {
  ProxyAutoLock lock;
  scoped_refptr<MockStringVar> var(new MockStringVar(std::string("xyz")));
  PP_Var pp_var = var->GetPPVar();
  EXPECT_TRUE(var->HasValidVarID());
  EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID()));

  // Releasing it should keep the object (because we have a ref) but reset the
  // var_id_.
  EXPECT_TRUE(var_tracker().ReleaseVar(pp_var));
  EXPECT_FALSE(var->HasValidVarID());
  EXPECT_EQ(1, mock_var_alive_count);

  var.reset();
  EXPECT_EQ(0, mock_var_alive_count);
}

TEST_F(VarTrackerTest, GetPluginRefAgain) {
  ProxyAutoLock lock;
  scoped_refptr<MockStringVar> var(new MockStringVar(std::string("xyz")));
  PP_Var pp_var = var->GetPPVar();
  EXPECT_TRUE(var_tracker().ReleaseVar(pp_var));
  EXPECT_FALSE(var->HasValidVarID());
  EXPECT_EQ(1, mock_var_alive_count);

  // Obtaining PP_Var ref again, and add ref from VarTracker.
  pp_var = var->GetPPVar();
  EXPECT_TRUE(var->HasValidVarID());
  EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID()));
  scoped_refptr<MockStringVar> another_var =
      static_cast<MockStringVar*>(var_tracker().GetVar(pp_var));
  EXPECT_EQ(1, mock_var_alive_count);

  // Releasing it again.
  EXPECT_TRUE(var_tracker().ReleaseVar(pp_var));
  EXPECT_FALSE(var->HasValidVarID());
  EXPECT_EQ(1, mock_var_alive_count);

  var.reset();
  EXPECT_FALSE(var_tracker().GetVar(pp_var));
  EXPECT_EQ(1, mock_var_alive_count);
  another_var.reset();
  EXPECT_FALSE(var_tracker().GetVar(pp_var));
  EXPECT_EQ(0, mock_var_alive_count);
}

// Tests when the plugin is holding a ref to a PP_Var when the instance is
// owned only by VarTracker.
TEST_F(VarTrackerTest, PluginRefWithoutVarRef) {
  ProxyAutoLock lock;
  // Make a PP_Var with one ref held by the plugin, and release the reference.
  scoped_refptr<MockStringVar> var(new MockStringVar(std::string("zzz")));
  PP_Var pp_var = var->GetPPVar();
  EXPECT_EQ(1, mock_var_alive_count);
  var.reset();
  EXPECT_EQ(1, mock_var_alive_count);

  // The var is owned only by VarTracker. PP_Var must be still valid.
  EXPECT_TRUE(var_tracker().GetVar(pp_var));

  var_tracker().ReleaseVar(pp_var);
  EXPECT_EQ(0, mock_var_alive_count);
  EXPECT_FALSE(var_tracker().GetVar(pp_var));
}

// Tests on Var having type of PP_VARTYPE_OBJECT.
TEST_F(VarTrackerTest, ObjectRef) {
  ProxyAutoLock lock;
  scoped_refptr<MockObjectVar> var(new MockObjectVar());
  PP_Var pp_var = var->GetPPVar();
  EXPECT_TRUE(var_tracker().ReleaseVar(pp_var));
  EXPECT_FALSE(var->HasValidVarID());
  EXPECT_EQ(1, mock_var_alive_count);

  // Obtaining PP_Var ref again, and add ref from VarTracker.
  pp_var = var->GetPPVar();
  EXPECT_TRUE(var->HasValidVarID());
  EXPECT_TRUE(var_tracker().GetVar(var->GetExistingVarID()));
  scoped_refptr<MockObjectVar> another_var =
      static_cast<MockObjectVar*>(var_tracker().GetVar(pp_var));
  EXPECT_EQ(1, mock_var_alive_count);

  // Releasing all references, then only VarTracker own the instance.
  var.reset();
  EXPECT_TRUE(var_tracker().GetVar(pp_var));
  EXPECT_EQ(1, mock_var_alive_count);
  another_var.reset();
  EXPECT_TRUE(var_tracker().GetVar(pp_var));
  EXPECT_EQ(1, mock_var_alive_count);

  // Releasing plugin reference.
  EXPECT_TRUE(var_tracker().ReleaseVar(pp_var));
  EXPECT_EQ(0, mock_var_alive_count);
}

}  // namespace ppapi
