// 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(absl::make_unique<int>(7));
  set1.insert(absl::make_unique<int>(17));

  set2.insert(absl::make_unique<int>(7));
  set2.insert(absl::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(absl::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(absl::make_unique<int>(17));
  EXPECT_TRUE(node);
  EXPECT_THAT(node.value(), Pointee(17));
  EXPECT_THAT(set1, UnorderedElementsAre(Pointee(19)));

  node.value() = absl::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
