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

#include "include/cppgc/allocation.h"
#include "include/cppgc/garbage-collected.h"
#include "src/base/build_config.h"
#include "test/unittests/heap/cppgc/tests.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cppgc {
namespace internal {

namespace {

struct NoName : public GarbageCollected<NoName> {
  virtual void Trace(Visitor*) const {}
};

struct OtherNoName : public GarbageCollected<OtherNoName> {
  virtual void Trace(Visitor*) const {}
};

class ClassWithName final : public GarbageCollected<OtherNoName>,
                            public NameProvider {
 public:
  explicit ClassWithName(const char* name) : name_(name) {}
  virtual void Trace(Visitor*) const {}
  const char* GetName() const final { return name_; }

 private:
  const char* name_;
};

}  // namespace

TEST(NameTraitTest, InternalNamesHiddenInOfficialBuild) {
  // Use a runtime test instead of static_assert to allow local builds but block
  // enabling the feature accidentally through the waterfall.
  //
  // Do not include such type information in official builds to
  // (a) save binary size on string literals, and
  // (b) avoid exposing internal types until it has been clarified whether
  //     exposing internals in DevTools is fine.
#if defined(OFFICIAL_BUILD)
  EXPECT_TRUE(NameProvider::HideInternalNames());
#endif
}

TEST(NameTraitTest, DefaultName) {
  EXPECT_STREQ(NameProvider::HideInternalNames()
                   ? "InternalNode"
                   : "cppgc::internal::(anonymous namespace)::NoName",
               NameTrait<NoName>::GetName(nullptr).value);
  EXPECT_STREQ(NameProvider::HideInternalNames()
                   ? "InternalNode"
                   : "cppgc::internal::(anonymous namespace)::OtherNoName",
               NameTrait<OtherNoName>::GetName(nullptr).value);
}

TEST(NameTraitTest, CustomName) {
  ClassWithName with_name("CustomName");
  const char* name = NameTrait<ClassWithName>::GetName(&with_name).value;
  EXPECT_STREQ("CustomName", name);
}

namespace {

class TraitTester : public NameTraitBase {
 public:
  // Expose type signature parser to allow testing various inputs.
  using NameTraitBase::GetNameFromTypeSignature;
};

}  // namespace

TEST(NameTraitTest, NoTypeAvailable) {
  HeapObjectName name = TraitTester::GetNameFromTypeSignature(nullptr);
  EXPECT_STREQ(NameProvider::kNoNameDeducible, name.value);
  EXPECT_TRUE(name.name_was_hidden);
}

TEST(NameTraitTest, ParsingPrettyFunction) {
  // Test assumes that __PRETTY_FUNCTION__ and friends return a string
  // containing the the type as [T = <type>].
  HeapObjectName name = TraitTester::GetNameFromTypeSignature(
      "Some signature of a method [T = ClassNameInSignature]");
  EXPECT_STREQ("ClassNameInSignature", name.value);
  EXPECT_FALSE(name.name_was_hidden);
  // While object names are generally leaky, the test needs to be cleaned up
  // gracefully.
  delete[] name.value;
}

class HeapObjectHeaderNameTest : public testing::TestWithHeap {};

TEST_F(HeapObjectHeaderNameTest, LookupNameThroughGCInfo) {
  auto* no_name = MakeGarbageCollected<NoName>(GetAllocationHandle());
  auto no_name_tuple = HeapObjectHeader::FromPayload(no_name).GetName();
  if (NameProvider::HideInternalNames()) {
    EXPECT_STREQ(NameProvider::kHiddenName, no_name_tuple.value);
    EXPECT_TRUE(no_name_tuple.name_was_hidden);
  } else {
    EXPECT_STREQ("cppgc::internal::(anonymous namespace)::NoName",
                 no_name_tuple.value);
    EXPECT_FALSE(no_name_tuple.name_was_hidden);
  }

  auto* other_no_name =
      MakeGarbageCollected<OtherNoName>(GetAllocationHandle());
  auto other_no_name_tuple =
      HeapObjectHeader::FromPayload(other_no_name).GetName();
  if (NameProvider::HideInternalNames()) {
    EXPECT_STREQ(NameProvider::kHiddenName, no_name_tuple.value);
    EXPECT_TRUE(no_name_tuple.name_was_hidden);
  } else {
    EXPECT_STREQ("cppgc::internal::(anonymous namespace)::OtherNoName",
                 other_no_name_tuple.value);
    EXPECT_FALSE(other_no_name_tuple.name_was_hidden);
  }

  auto* class_with_name =
      MakeGarbageCollected<ClassWithName>(GetAllocationHandle(), "CustomName");
  auto class_with_name_tuple =
      HeapObjectHeader::FromPayload(class_with_name).GetName();
  EXPECT_STREQ("CustomName", class_with_name_tuple.value);
  EXPECT_FALSE(class_with_name_tuple.name_was_hidden);
}

}  // namespace internal
}  // namespace cppgc
