// 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 "testing/fxgc_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/v8_test_environment.h"
#include "third_party/base/containers/contains.h"
#include "v8/include/cppgc/allocation.h"
#include "v8/include/cppgc/persistent.h"

namespace {

class PseudoCollectible : public cppgc::GarbageCollected<PseudoCollectible> {
 public:
  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_;

class CollectibleHolder {
 public:
  explicit CollectibleHolder(PseudoCollectible* holdee) : holdee_(holdee) {}
  ~CollectibleHolder() = default;

  PseudoCollectible* holdee() const { return holdee_; }

 private:
  cppgc::Persistent<PseudoCollectible> holdee_;
};

class Bloater : public cppgc::GarbageCollected<Bloater> {
 public:
  void Trace(cppgc::Visitor* visitor) const {}
  uint8_t bloat_[65536];
};

}  // 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);
  {
    auto holder = std::make_unique<CollectibleHolder>(
        cppgc::MakeGarbageCollected<PseudoCollectible>(
            heap1->GetAllocationHandle()));

    EXPECT_TRUE(holder->holdee()->IsLive());
    EXPECT_EQ(1u, PseudoCollectible::LiveCount());
    EXPECT_EQ(0u, PseudoCollectible::DeadCount());
  }
  FXGC_ForceGarbageCollection(heap1.get());
  EXPECT_EQ(0u, PseudoCollectible::LiveCount());
  EXPECT_EQ(1u, PseudoCollectible::DeadCount());
}

TEST_F(HeapUnitTest, HasReferences) {
  FXGCScopedHeap heap1 = FXGC_CreateHeap();
  ASSERT_TRUE(heap1);
  {
    auto holder = std::make_unique<CollectibleHolder>(
        cppgc::MakeGarbageCollected<PseudoCollectible>(
            heap1->GetAllocationHandle()));

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

    FXGC_ForceGarbageCollection(heap1.get());
    EXPECT_TRUE(holder->holdee()->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);
  {
    auto holder = std::make_unique<CollectibleHolder>(
        cppgc::MakeGarbageCollected<PseudoCollectible>(
            heap1->GetAllocationHandle()));

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

    heap1.reset();

    // Maybe someday magically nulled by heap destruction.
    EXPECT_FALSE(holder->holdee());
    EXPECT_EQ(1u, PseudoCollectible::LiveCount());
    EXPECT_EQ(0u, PseudoCollectible::DeadCount());
  }
}

TEST_F(HeapUnitTest, DeleteHeapNoReferences) {
  FXGCScopedHeap heap1 = FXGC_CreateHeap();
  ASSERT_TRUE(heap1);
  {
    auto holder = std::make_unique<CollectibleHolder>(
        cppgc::MakeGarbageCollected<PseudoCollectible>(
            heap1->GetAllocationHandle()));

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

TEST_F(HeapUnitTest, Bloat) {
  ASSERT_TRUE(heap());
  for (int i = 0; i < 100000; ++i) {
    cppgc::MakeGarbageCollected<Bloater>(heap()->GetAllocationHandle());
    Pump();  // Do not force GC, must happen implicitly when space required.
  }
}
