// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/scoped_generic.h"

#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_set.h"

namespace base {

namespace {

struct IntTraits {
  explicit IntTraits(std::vector<int>* freed) : freed_ints(freed) {}

  static int InvalidValue() { return -1; }
  void Free(int value) { freed_ints->push_back(value); }

  raw_ptr<std::vector<int>> freed_ints;
};

using ScopedInt = ScopedGeneric<int, IntTraits>;

}  // namespace

TEST(ScopedGenericTest, ScopedGeneric) {
  std::vector<int> values_freed;
  IntTraits traits(&values_freed);

  // Invalid case, delete should not be called.
  {
    ScopedInt a(IntTraits::InvalidValue(), traits);
  }
  EXPECT_TRUE(values_freed.empty());

  // Simple deleting case.
  static const int kFirst = 0;
  {
    ScopedInt a(kFirst, traits);
  }
  ASSERT_EQ(1u, values_freed.size());
  ASSERT_EQ(kFirst, values_freed[0]);
  values_freed.clear();

  // Release should return the right value and leave the object empty.
  {
    ScopedInt a(kFirst, traits);
    EXPECT_EQ(kFirst, a.release());

    ScopedInt b(IntTraits::InvalidValue(), traits);
    EXPECT_EQ(IntTraits::InvalidValue(), b.release());
  }
  ASSERT_TRUE(values_freed.empty());

  // Reset should free the old value, then the new one should go away when
  // it goes out of scope.
  static const int kSecond = 1;
  {
    ScopedInt b(kFirst, traits);
    b.reset(kSecond);
    ASSERT_EQ(1u, values_freed.size());
    ASSERT_EQ(kFirst, values_freed[0]);
  }
  ASSERT_EQ(2u, values_freed.size());
  ASSERT_EQ(kSecond, values_freed[1]);
  values_freed.clear();

  // Move constructor.
  {
    ScopedInt a(kFirst, traits);
    ScopedInt b(std::move(a));
    EXPECT_TRUE(values_freed.empty());  // Nothing should be freed.
    ASSERT_EQ(IntTraits::InvalidValue(),
              a.get());  // NOLINT(bugprone-use-after-move)
    ASSERT_EQ(kFirst, b.get());
  }

  ASSERT_EQ(1u, values_freed.size());
  ASSERT_EQ(kFirst, values_freed[0]);
  values_freed.clear();

  // Move assign.
  {
    ScopedInt a(kFirst, traits);
    ScopedInt b(kSecond, traits);
    b = std::move(a);
    ASSERT_EQ(1u, values_freed.size());
    EXPECT_EQ(kSecond, values_freed[0]);
    ASSERT_EQ(IntTraits::InvalidValue(),
              a.get());  // NOLINT(bugprone-use-after-move)
    ASSERT_EQ(kFirst, b.get());
  }

  ASSERT_EQ(2u, values_freed.size());
  EXPECT_EQ(kFirst, values_freed[1]);
  values_freed.clear();
}

TEST(ScopedGenericTest, Operators) {
  std::vector<int> values_freed;
  IntTraits traits(&values_freed);

  static const int kFirst = 0;
  static const int kSecond = 1;
  {
    ScopedInt a(kFirst, traits);
    EXPECT_TRUE(a == kFirst);
    EXPECT_FALSE(a != kFirst);
    EXPECT_FALSE(a == kSecond);
    EXPECT_TRUE(a != kSecond);

    EXPECT_TRUE(kFirst == a);
    EXPECT_FALSE(kFirst != a);
    EXPECT_FALSE(kSecond == a);
    EXPECT_TRUE(kSecond != a);
  }

  // is_valid().
  {
    ScopedInt a(kFirst, traits);
    EXPECT_TRUE(a.is_valid());
    a.reset();
    EXPECT_FALSE(a.is_valid());
  }
}

TEST(ScopedGenericTest, Receive) {
  std::vector<int> values_freed;
  IntTraits traits(&values_freed);
  auto a = std::make_unique<ScopedInt>(123, traits);

  EXPECT_EQ(123, a->get());

  {
    ScopedInt::Receiver r(*a);
    EXPECT_EQ(123, a->get());
    *r.get() = 456;
    EXPECT_EQ(123, a->get());
  }

  EXPECT_EQ(456, a->get());

  {
    ScopedInt::Receiver r(*a);
    EXPECT_DEATH_IF_SUPPORTED(a.reset(), "");
    EXPECT_DEATH_IF_SUPPORTED(ScopedInt::Receiver(*a).get(), "");
  }
}

namespace {

struct TrackedIntTraits : public ScopedGenericOwnershipTracking {
  using OwnerMap = std::unordered_map<
      int,
      raw_ptr<const ScopedGeneric<int, TrackedIntTraits>, CtnExperimental>>;
  TrackedIntTraits(absl::flat_hash_set<int>* freed, OwnerMap* owners)
      : freed(freed), owners(owners) {}

  static int InvalidValue() { return -1; }

  void Free(int value) {
    auto it = owners->find(value);
    ASSERT_EQ(owners->end(), it);

    ASSERT_EQ(0U, freed->count(value));
    freed->insert(value);
  }

  void Acquire(const ScopedGeneric<int, TrackedIntTraits>& owner, int value) {
    auto it = owners->find(value);
    ASSERT_EQ(owners->end(), it);
    (*owners)[value] = &owner;
  }

  void Release(const ScopedGeneric<int, TrackedIntTraits>& owner, int value) {
    auto it = owners->find(value);
    ASSERT_NE(owners->end(), it);
    owners->erase(it);
  }

  raw_ptr<absl::flat_hash_set<int>> freed;
  raw_ptr<OwnerMap> owners;
};

using ScopedTrackedInt = ScopedGeneric<int, TrackedIntTraits>;

}  // namespace

TEST(ScopedGenericTest, OwnershipTracking) {
  TrackedIntTraits::OwnerMap owners;
  absl::flat_hash_set<int> freed;
  TrackedIntTraits traits(&freed, &owners);

#define ASSERT_OWNED(value, owner)     \
  ASSERT_TRUE(owners.contains(value)); \
  ASSERT_EQ(&owner, owners[value]);    \
  ASSERT_FALSE(freed.contains(value))

#define ASSERT_UNOWNED(value)           \
  ASSERT_FALSE(owners.contains(value)); \
  ASSERT_FALSE(freed.contains(value))

#define ASSERT_FREED(value)             \
  ASSERT_FALSE(owners.contains(value)); \
  ASSERT_TRUE(freed.contains(value))

  // Constructor.
  {
    {
      ScopedTrackedInt a(0, traits);
      ASSERT_OWNED(0, a);
    }
    ASSERT_FREED(0);
  }

  owners.clear();
  freed.clear();

  // Reset.
  {
    ScopedTrackedInt a(0, traits);
    ASSERT_OWNED(0, a);
    a.reset(1);
    ASSERT_FREED(0);
    ASSERT_OWNED(1, a);
    a.reset();
    ASSERT_FREED(0);
    ASSERT_FREED(1);
  }

  owners.clear();
  freed.clear();

  // Release.
  {
    {
      ScopedTrackedInt a(0, traits);
      ASSERT_OWNED(0, a);
      int released = a.release();
      ASSERT_EQ(0, released);
      ASSERT_UNOWNED(0);
    }
    ASSERT_UNOWNED(0);
  }

  owners.clear();
  freed.clear();

  // Move constructor.
  {
    ScopedTrackedInt a(0, traits);
    ASSERT_OWNED(0, a);
    {
      ScopedTrackedInt b(std::move(a));
      ASSERT_OWNED(0, b);
    }
    ASSERT_FREED(0);
  }

  owners.clear();
  freed.clear();

  // Move assignment.
  {
    {
      ScopedTrackedInt a(0, traits);
      ScopedTrackedInt b(1, traits);
      ASSERT_OWNED(0, a);
      ASSERT_OWNED(1, b);
      a = std::move(b);
      ASSERT_OWNED(1, a);
      ASSERT_FREED(0);
    }
    ASSERT_FREED(1);
  }

  owners.clear();
  freed.clear();

#undef ASSERT_OWNED
#undef ASSERT_UNOWNED
#undef ASSERT_FREED
}

// Cheesy manual "no compile" test for manually validating changes.
#if 0
TEST(ScopedGenericTest, NoCompile) {
  // Assignment shouldn't work.
  /*{
    ScopedInt a(kFirst, traits);
    ScopedInt b(a);
  }*/

  // Comparison shouldn't work.
  /*{
    ScopedInt a(kFirst, traits);
    ScopedInt b(kFirst, traits);
    if (a == b) {
    }
  }*/

  // Implicit conversion to bool shouldn't work.
  /*{
    ScopedInt a(kFirst, traits);
    bool result = a;
  }*/
}
#endif

}  // namespace base
