// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/container/flat_hash_set.h"

#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/container/hash_container_defaults.h"
#include "absl/container/internal/container_memory.h"
#include "absl/container/internal/hash_generator_testing.h"
#include "absl/container/internal/test_allocator.h"
#include "absl/container/internal/unordered_set_constructor_test.h"
#include "absl/container/internal/unordered_set_lookup_test.h"
#include "absl/container/internal/unordered_set_members_test.h"
#include "absl/container/internal/unordered_set_modifiers_test.h"
#include "absl/hash/hash.h"
#include "absl/log/check.h"
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"

#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
#include <ranges>  // NOLINT(build/c++20)
#endif

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {
namespace {

using ::testing::IsEmpty;
using ::testing::Pointee;
using ::testing::UnorderedElementsAre;
using ::testing::UnorderedElementsAreArray;

// Check that absl::flat_hash_set works in a global constructor.
struct BeforeMain {
  BeforeMain() {
    absl::flat_hash_set<int> x;
    x.insert(1);
    CHECK(!x.contains(0)) << "x should not contain 0";
    CHECK(x.contains(1)) << "x should contain 1";
  }
};
const BeforeMain before_main;

template <class T>
using Set =
    absl::flat_hash_set<T, StatefulTestingHash, StatefulTestingEqual, Alloc<T>>;

using SetTypes =
    ::testing::Types<Set<int>, Set<std::string>, Set<Enum>, Set<EnumClass>>;

INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashSet, ConstructorTest, SetTypes);
INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashSet, LookupTest, SetTypes);
INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashSet, MembersTest, SetTypes);
INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashSet, ModifiersTest, SetTypes);

TEST(FlatHashSet, EmplaceString) {
  std::vector<std::string> v = {"a", "b"};
  absl::flat_hash_set<absl::string_view> hs(v.begin(), v.end());
  EXPECT_THAT(hs, UnorderedElementsAreArray(v));
}

TEST(FlatHashSet, BitfieldArgument) {
  union {
    int n : 1;
  };
  n = 0;
  absl::flat_hash_set<int> s = {n};
  s.insert(n);
  s.insert(s.end(), n);
  s.insert({n});
  s.erase(n);
  s.count(n);
  s.prefetch(n);
  s.find(n);
  s.contains(n);
  s.equal_range(n);
}

TEST(FlatHashSet, MergeExtractInsert) {
  struct Hash {
    size_t operator()(const std::unique_ptr<int>& p) const { return *p; }
  };
  struct Eq {
    bool operator()(const std::unique_ptr<int>& a,
                    const std::unique_ptr<int>& b) const {
      return *a == *b;
    }
  };
  absl::flat_hash_set<std::unique_ptr<int>, Hash, Eq> set1, set2;
  set1.insert(std::make_unique<int>(7));
  set1.insert(std::make_unique<int>(17));

  set2.insert(std::make_unique<int>(7));
  set2.insert(std::make_unique<int>(19));

  EXPECT_THAT(set1, UnorderedElementsAre(Pointee(7), Pointee(17)));
  EXPECT_THAT(set2, UnorderedElementsAre(Pointee(7), Pointee(19)));

  set1.merge(set2);

  EXPECT_THAT(set1, UnorderedElementsAre(Pointee(7), Pointee(17), Pointee(19)));
  EXPECT_THAT(set2, UnorderedElementsAre(Pointee(7)));

  auto node = set1.extract(std::make_unique<int>(7));
  EXPECT_TRUE(node);
  EXPECT_THAT(node.value(), Pointee(7));
  EXPECT_THAT(set1, UnorderedElementsAre(Pointee(17), Pointee(19)));

  auto insert_result = set2.insert(std::move(node));
  EXPECT_FALSE(node);
  EXPECT_FALSE(insert_result.inserted);
  EXPECT_TRUE(insert_result.node);
  EXPECT_THAT(insert_result.node.value(), Pointee(7));
  EXPECT_EQ(**insert_result.position, 7);
  EXPECT_NE(insert_result.position->get(), insert_result.node.value().get());
  EXPECT_THAT(set2, UnorderedElementsAre(Pointee(7)));

  node = set1.extract(std::make_unique<int>(17));
  EXPECT_TRUE(node);
  EXPECT_THAT(node.value(), Pointee(17));
  EXPECT_THAT(set1, UnorderedElementsAre(Pointee(19)));

  node.value() = std::make_unique<int>(23);

  insert_result = set2.insert(std::move(node));
  EXPECT_FALSE(node);
  EXPECT_TRUE(insert_result.inserted);
  EXPECT_FALSE(insert_result.node);
  EXPECT_EQ(**insert_result.position, 23);
  EXPECT_THAT(set2, UnorderedElementsAre(Pointee(7), Pointee(23)));
}

bool IsEven(int k) { return k % 2 == 0; }

TEST(FlatHashSet, EraseIf) {
  // Erase all elements.
  {
    flat_hash_set<int> s = {1, 2, 3, 4, 5};
    EXPECT_EQ(erase_if(s, [](int) { return true; }), 5);
    EXPECT_THAT(s, IsEmpty());
  }
  // Erase no elements.
  {
    flat_hash_set<int> s = {1, 2, 3, 4, 5};
    EXPECT_EQ(erase_if(s, [](int) { return false; }), 0);
    EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
  }
  // Erase specific elements.
  {
    flat_hash_set<int> s = {1, 2, 3, 4, 5};
    EXPECT_EQ(erase_if(s, [](int k) { return k % 2 == 1; }), 3);
    EXPECT_THAT(s, UnorderedElementsAre(2, 4));
  }
  // Predicate is function reference.
  {
    flat_hash_set<int> s = {1, 2, 3, 4, 5};
    EXPECT_EQ(erase_if(s, IsEven), 2);
    EXPECT_THAT(s, UnorderedElementsAre(1, 3, 5));
  }
  // Predicate is function pointer.
  {
    flat_hash_set<int> s = {1, 2, 3, 4, 5};
    EXPECT_EQ(erase_if(s, &IsEven), 2);
    EXPECT_THAT(s, UnorderedElementsAre(1, 3, 5));
  }
}

TEST(FlatHashSet, CForEach) {
  using ValueType = std::pair<int, int>;
  flat_hash_set<ValueType> s;
  std::vector<ValueType> expected;
  for (int i = 0; i < 100; ++i) {
    {
      SCOPED_TRACE("mutable object iteration");
      std::vector<ValueType> v;
      absl::container_internal::c_for_each_fast(
          s, [&v](const ValueType& p) { v.push_back(p); });
      ASSERT_THAT(v, UnorderedElementsAreArray(expected));
    }
    {
      SCOPED_TRACE("const object iteration");
      std::vector<ValueType> v;
      const flat_hash_set<ValueType>& cs = s;
      absl::container_internal::c_for_each_fast(
          cs, [&v](const ValueType& p) { v.push_back(p); });
      ASSERT_THAT(v, UnorderedElementsAreArray(expected));
    }
    {
      SCOPED_TRACE("temporary object iteration");
      std::vector<ValueType> v;
      absl::container_internal::c_for_each_fast(
          flat_hash_set<ValueType>(s),
          [&v](const ValueType& p) { v.push_back(p); });
      ASSERT_THAT(v, UnorderedElementsAreArray(expected));
    }
    s.emplace(i, i);
    expected.emplace_back(i, i);
  }
}

class PoisonSoo {
  int64_t data_;

 public:
  explicit PoisonSoo(int64_t d) : data_(d) { SanitizerPoisonObject(&data_); }
  PoisonSoo(const PoisonSoo& that) : PoisonSoo(*that) {}
  ~PoisonSoo() { SanitizerUnpoisonObject(&data_); }

  int64_t operator*() const {
    SanitizerUnpoisonObject(&data_);
    const int64_t ret = data_;
    SanitizerPoisonObject(&data_);
    return ret;
  }
  template <typename H>
  friend H AbslHashValue(H h, const PoisonSoo& pi) {
    return H::combine(std::move(h), *pi);
  }
  bool operator==(const PoisonSoo& rhs) const { return **this == *rhs; }
};

TEST(FlatHashSet, PoisonSooBasic) {
  PoisonSoo a(0), b(1);
  flat_hash_set<PoisonSoo> set;
  set.insert(a);
  EXPECT_THAT(set, UnorderedElementsAre(a));
  set.insert(b);
  EXPECT_THAT(set, UnorderedElementsAre(a, b));
  set.erase(a);
  EXPECT_THAT(set, UnorderedElementsAre(b));
  set.rehash(0);  // Shrink to SOO.
  EXPECT_THAT(set, UnorderedElementsAre(b));
}

TEST(FlatHashSet, PoisonSooMoveConstructSooToSoo) {
  PoisonSoo a(0);
  flat_hash_set<PoisonSoo> set;
  set.insert(a);
  flat_hash_set<PoisonSoo> set2(std::move(set));
  EXPECT_THAT(set2, UnorderedElementsAre(a));
}

TEST(FlatHashSet, PoisonSooAllocMoveConstructSooToSoo) {
  PoisonSoo a(0);
  flat_hash_set<PoisonSoo> set;
  set.insert(a);
  flat_hash_set<PoisonSoo> set2(std::move(set), std::allocator<PoisonSoo>());
  EXPECT_THAT(set2, UnorderedElementsAre(a));
}

TEST(FlatHashSet, PoisonSooMoveAssignFullSooToEmptySoo) {
  PoisonSoo a(0);
  flat_hash_set<PoisonSoo> set, set2;
  set.insert(a);
  set2 = std::move(set);
  EXPECT_THAT(set2, UnorderedElementsAre(a));
}

TEST(FlatHashSet, PoisonSooMoveAssignFullSooToFullSoo) {
  PoisonSoo a(0), b(1);
  flat_hash_set<PoisonSoo> set, set2;
  set.insert(a);
  set2.insert(b);
  set2 = std::move(set);
  EXPECT_THAT(set2, UnorderedElementsAre(a));
}

TEST(FlatHashSet, FlatHashSetPolicyDestroyReturnsTrue) {
  EXPECT_TRUE((decltype(FlatHashSetPolicy<int>::destroy<std::allocator<int>>(
      nullptr, nullptr))()));
  EXPECT_FALSE(
      (decltype(FlatHashSetPolicy<int>::destroy<CountingAllocator<int>>(
          nullptr, nullptr))()));
  EXPECT_FALSE((decltype(FlatHashSetPolicy<std::unique_ptr<int>>::destroy<
                         std::allocator<int>>(nullptr, nullptr))()));
}

struct HashEqInvalidOnMove {
  HashEqInvalidOnMove() = default;
  HashEqInvalidOnMove(const HashEqInvalidOnMove& rhs) = default;
  HashEqInvalidOnMove(HashEqInvalidOnMove&& rhs) { rhs.moved = true; }
  HashEqInvalidOnMove& operator=(const HashEqInvalidOnMove& rhs) = default;
  HashEqInvalidOnMove& operator=(HashEqInvalidOnMove&& rhs) {
    rhs.moved = true;
    return *this;
  }

  size_t operator()(int x) const {
    CHECK(!moved);
    return absl::HashOf(x);
  }

  bool operator()(int x, int y) const {
    CHECK(!moved);
    return x == y;
  }

  bool moved = false;
};

TEST(FlatHashSet, MovedFromCleared_HashMustBeValid) {
  flat_hash_set<int, HashEqInvalidOnMove> s1, s2;
  // Moving the hashtable must not move the hasher because we need to support
  // this behavior.
  s2 = std::move(s1);
  s1.clear();
  s1.insert(2);
  EXPECT_THAT(s1, UnorderedElementsAre(2));
}

TEST(FlatHashSet, MovedFromCleared_EqMustBeValid) {
  flat_hash_set<int, DefaultHashContainerHash<int>, HashEqInvalidOnMove> s1, s2;
  // Moving the hashtable must not move the equality functor because we need to
  // support this behavior.
  s2 = std::move(s1);
  s1.clear();
  s1.insert(2);
  EXPECT_THAT(s1, UnorderedElementsAre(2));
}

TEST(FlatHashSet, Equality) {
  {
    flat_hash_set<int> s1 = {1, 2, 3};
    flat_hash_set<int> s2 = {1, 2, 3};
    EXPECT_EQ(s1, s2);
  }
  {
    flat_hash_set<std::string> s1 = {"a", "b", "c"};
    flat_hash_set<std::string> s2 = {"a", "b", "c"};
    EXPECT_EQ(s1, s2);
  }
}

class MoveOnlyInt {
 public:
  explicit MoveOnlyInt(int value) : value_(value) {}

  MoveOnlyInt(const MoveOnlyInt& other) = delete;
  MoveOnlyInt& operator=(const MoveOnlyInt& other) = delete;

  MoveOnlyInt(MoveOnlyInt&& other) = default;
  MoveOnlyInt& operator=(MoveOnlyInt&& other) = default;

  bool operator==(const MoveOnlyInt& other) const {
    return value_ == other.value_;
  }
  bool operator==(int other) const { return value_ == other; }

 private:
  template <typename H>
  friend H AbslHashValue(H h, const MoveOnlyInt& m) {
    return H::combine(std::move(h), m.value_);
  }

  int value_;
};

TEST(FlatHashSet, MoveOnlyKey) {
  flat_hash_set<MoveOnlyInt> s;
  s.insert(MoveOnlyInt(1));
  s.insert(MoveOnlyInt(2));
  s.insert(MoveOnlyInt(3));
  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3));
}

TEST(FlatHashSet, IsDefaultHash) {
  using absl::container_internal::hashtable_debug_internal::
      HashtableDebugAccess;
  EXPECT_EQ(HashtableDebugAccess<flat_hash_set<int>>::kIsDefaultHash, true);
  EXPECT_EQ(HashtableDebugAccess<flat_hash_set<std::string>>::kIsDefaultHash,
            true);

  struct Hash {
    size_t operator()(size_t i) const { return i; }
  };
  EXPECT_EQ((HashtableDebugAccess<flat_hash_set<size_t, Hash>>::kIsDefaultHash),
            false);
}

#if defined(__cpp_lib_containers_ranges) && \
    __cpp_lib_containers_ranges >= 202202L
TEST(FlatHashSet, FromRange) {
  std::vector<int> v = {1, 2, 3, 4, 5};
  absl::flat_hash_set<int> s(std::from_range, v);
  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
}

TEST(FlatHashSet, FromRangeWithAllocator) {
  std::vector<int> v = {1, 2, 3, 4, 5};
  absl::flat_hash_set<int, absl::container_internal::hash_default_hash<int>,
                      absl::container_internal::hash_default_eq<int>,
                      Alloc<int>>
      s(std::from_range, v, 0, Alloc<int>());
  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
}

TEST(FlatHashSet, FromRangeWithHasherAndAllocator) {
  std::vector<int> v = {1, 2, 3, 4, 5};
  using TestingHash = absl::container_internal::StatefulTestingHash;
  absl::flat_hash_set<int, TestingHash,
                      absl::container_internal::hash_default_eq<int>,
                      Alloc<int>>
      s(std::from_range, v, 0, TestingHash{}, Alloc<int>());
  EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5));
}
#endif

}  // namespace
}  // namespace container_internal
ABSL_NAMESPACE_END
}  // namespace absl
