// Copyright 2020 the V8 project 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 "include/cppgc/internal/finalizer-trait.h"

#include <type_traits>

#include "testing/gtest/include/gtest/gtest.h"

namespace cppgc {
namespace internal {

namespace {

// Trivially destructible types.
class TypeWithoutDestructor final {};
class TypeWithPrimitive final {
 public:
  int foo = 0;
};

class InvokeCounter {
 public:
  static size_t kCallcount;
  static void Reset() { kCallcount = 0; }
  static void Invoke() { kCallcount++; }
};

size_t InvokeCounter::kCallcount = 0;

// Regular C++ use cases.

class TypeWithDestructor final : public InvokeCounter {
 public:
  ~TypeWithDestructor() { Invoke(); }
};

class TypeWithVirtualDestructorBase {
 public:
  virtual ~TypeWithVirtualDestructorBase() = default;
};

class TypeWithVirtualDestructorChild final
    : public TypeWithVirtualDestructorBase,
      public InvokeCounter {
 public:
  ~TypeWithVirtualDestructorChild() final { Invoke(); }
};

// Manual dispatch to avoid vtables.

class TypeWithCustomFinalizationMethod final : public InvokeCounter {
 public:
  void FinalizeGarbageCollectedObject() { Invoke(); }
};

class TypeWithCustomFinalizationMethodAtBase {
 public:
  void FinalizeGarbageCollectedObject();
};

class TypeWithCustomFinalizationMethodAtBaseChild
    : public TypeWithCustomFinalizationMethodAtBase,
      public InvokeCounter {
 public:
  ~TypeWithCustomFinalizationMethodAtBaseChild() { Invoke(); }
};

void TypeWithCustomFinalizationMethodAtBase::FinalizeGarbageCollectedObject() {
  // The test knows that base is only inherited by a single child. In practice
  // users can maintain a map of valid types in already existing storage.
  static_cast<TypeWithCustomFinalizationMethodAtBaseChild*>(this)
      ->~TypeWithCustomFinalizationMethodAtBaseChild();
}

template <typename Type>
void ExpectFinalizerIsInvoked(Type* object) {
  InvokeCounter::Reset();
  EXPECT_NE(nullptr, FinalizerTrait<Type>::kCallback);
  FinalizerTrait<Type>::kCallback(object);
  EXPECT_EQ(1u, InvokeCounter::kCallcount);
  operator delete(object);
}

}  // namespace

TEST(FinalizerTrait, TypeWithoutDestructorHasNoFinalizer) {
  static_assert(std::is_trivially_destructible<TypeWithoutDestructor>::value,
                "trivially destructible");
  EXPECT_EQ(nullptr, FinalizerTrait<TypeWithoutDestructor>::kCallback);
}

TEST(FinalizerTrait, TypeWithPrimitiveHasNoFinalizer) {
  static_assert(std::is_trivially_destructible<TypeWithPrimitive>::value,
                "trivially destructible");
  EXPECT_EQ(nullptr, FinalizerTrait<TypeWithPrimitive>::kCallback);
}

TEST(FinalizerTrait, FinalizerForTypeWithDestructor) {
  ExpectFinalizerIsInvoked(new TypeWithDestructor());
}

TEST(FinalizerTrait, FinalizerForTypeWithVirtualBaseDtor) {
  TypeWithVirtualDestructorBase* base = new TypeWithVirtualDestructorChild();
  ExpectFinalizerIsInvoked(base);
}

TEST(FinalizerTrait, FinalizerForCustomFinalizationMethod) {
  ExpectFinalizerIsInvoked(new TypeWithCustomFinalizationMethod());
}

TEST(FinalizerTrait, FinalizerForCustomFinalizationMethodInBase) {
  TypeWithCustomFinalizationMethodAtBase* base =
      new TypeWithCustomFinalizationMethodAtBaseChild();
  ExpectFinalizerIsInvoked(base);
}

}  // namespace internal
}  // namespace cppgc
