// Copyright 2020 PDFium 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 "fxjs/gc/heap.h"

#include <memory>
#include <set>

#include "core/fxcrt/autorestorer.h"
#include "testing/fxgc_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/base/stl_util.h"
#include "v8/include/cppgc/allocation.h"
#include "v8/include/cppgc/persistent.h"

namespace {

class PseudoCollectible : public cppgc::GarbageCollected<PseudoCollectible> {
 public:
  static cppgc::Persistent<PseudoCollectible> s_persistent_;

  static void ClearCounts() {
    s_live_.clear();
    s_dead_.clear();
  }
  static size_t LiveCount() { return s_live_.size(); }
  static size_t DeadCount() { return s_dead_.size(); }

  PseudoCollectible() { s_live_.insert(this); }
  virtual ~PseudoCollectible() {
    s_live_.erase(this);
    s_dead_.insert(this);
  }

  bool IsLive() const { return pdfium::Contains(s_live_, this); }

  virtual void Trace(cppgc::Visitor* visitor) const {}

 private:
  static std::set<const PseudoCollectible*> s_live_;
  static std::set<const PseudoCollectible*> s_dead_;
};

std::set<const PseudoCollectible*> PseudoCollectible::s_live_;
std::set<const PseudoCollectible*> PseudoCollectible::s_dead_;
cppgc::Persistent<PseudoCollectible> PseudoCollectible::s_persistent_;

}  // namespace

class HeapUnitTest : public FXGCUnitTest {
 public:
  HeapUnitTest() = default;
  ~HeapUnitTest() override = default;

  // FXGCUnitTest:
  void TearDown() override {
    PseudoCollectible::ClearCounts();
    FXGCUnitTest::TearDown();
  }
};

TEST_F(HeapUnitTest, SeveralHeaps) {
  FXGCScopedHeap heap1 = FXGC_CreateHeap();
  EXPECT_TRUE(heap1);

  FXGCScopedHeap heap2 = FXGC_CreateHeap();
  EXPECT_TRUE(heap2);

  FXGCScopedHeap heap3 = FXGC_CreateHeap();
  EXPECT_TRUE(heap3);

  // Test manually destroying the heap.
  heap3.reset();
  EXPECT_FALSE(heap3);
  heap3.reset();
  EXPECT_FALSE(heap3);
}

TEST_F(HeapUnitTest, NoReferences) {
  FXGCScopedHeap heap1 = FXGC_CreateHeap();
  ASSERT_TRUE(heap1);
  {
    ASSERT_FALSE(PseudoCollectible::s_persistent_);
    AutoRestorer<cppgc::Persistent<PseudoCollectible>> restorer(
        &PseudoCollectible::s_persistent_);

    PseudoCollectible::s_persistent_ =
        cppgc::MakeGarbageCollected<PseudoCollectible>(
            heap1->GetAllocationHandle());

    EXPECT_TRUE(PseudoCollectible::s_persistent_->IsLive());
    EXPECT_EQ(1u, PseudoCollectible::LiveCount());
    EXPECT_EQ(0u, PseudoCollectible::DeadCount());
  }
  heap1->ForceGarbageCollectionSlow("NoReferences", "test",
                                    cppgc::Heap::StackState::kNoHeapPointers);
  EXPECT_EQ(0u, PseudoCollectible::LiveCount());
  EXPECT_EQ(1u, PseudoCollectible::DeadCount());
}

TEST_F(HeapUnitTest, HasReferences) {
  FXGCScopedHeap heap1 = FXGC_CreateHeap();
  ASSERT_TRUE(heap1);
  {
    ASSERT_FALSE(PseudoCollectible::s_persistent_);
    AutoRestorer<cppgc::Persistent<PseudoCollectible>> restorer(
        &PseudoCollectible::s_persistent_);

    PseudoCollectible::s_persistent_ =
        cppgc::MakeGarbageCollected<PseudoCollectible>(
            heap1->GetAllocationHandle());

    EXPECT_TRUE(PseudoCollectible::s_persistent_->IsLive());
    EXPECT_EQ(1u, PseudoCollectible::LiveCount());
    EXPECT_EQ(0u, PseudoCollectible::DeadCount());

    heap1->ForceGarbageCollectionSlow("HasReferences", "test",
                                      cppgc::Heap::StackState::kNoHeapPointers);

    EXPECT_TRUE(PseudoCollectible::s_persistent_->IsLive());
    EXPECT_EQ(1u, PseudoCollectible::LiveCount());
    EXPECT_EQ(0u, PseudoCollectible::DeadCount());
  }
}

// TODO(tsepez): enable when CPPGC fixes this segv.
TEST_F(HeapUnitTest, DISABLED_DeleteHeapHasReferences) {
  FXGCScopedHeap heap1 = FXGC_CreateHeap();
  ASSERT_TRUE(heap1);
  {
    ASSERT_FALSE(PseudoCollectible::s_persistent_);
    AutoRestorer<cppgc::Persistent<PseudoCollectible>> restorer(
        &PseudoCollectible::s_persistent_);

    PseudoCollectible::s_persistent_ =
        cppgc::MakeGarbageCollected<PseudoCollectible>(
            heap1->GetAllocationHandle());

    EXPECT_TRUE(PseudoCollectible::s_persistent_->IsLive());
    EXPECT_EQ(1u, PseudoCollectible::LiveCount());
    EXPECT_EQ(0u, PseudoCollectible::DeadCount());

    heap1.reset();
    EXPECT_FALSE(PseudoCollectible::s_persistent_);
    EXPECT_EQ(1u, PseudoCollectible::LiveCount());
    EXPECT_EQ(0u, PseudoCollectible::DeadCount());
  }
}

TEST_F(HeapUnitTest, DeleteHeapNoReferences) {
  FXGCScopedHeap heap1 = FXGC_CreateHeap();
  ASSERT_TRUE(heap1);
  {
    ASSERT_FALSE(PseudoCollectible::s_persistent_);
    AutoRestorer<cppgc::Persistent<PseudoCollectible>> restorer(
        &PseudoCollectible::s_persistent_);

    PseudoCollectible::s_persistent_ =
        cppgc::MakeGarbageCollected<PseudoCollectible>(
            heap1->GetAllocationHandle());

    EXPECT_TRUE(PseudoCollectible::s_persistent_->IsLive());
    EXPECT_EQ(1u, PseudoCollectible::LiveCount());
    EXPECT_EQ(0u, PseudoCollectible::DeadCount());
  }
  heap1.reset();
  EXPECT_EQ(0u, PseudoCollectible::LiveCount());
  EXPECT_EQ(1u, PseudoCollectible::DeadCount());
}
