// 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.

#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MODIFIERS_TEST_H_
#define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MODIFIERS_TEST_H_

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/container/internal/hash_generator_testing.h"
#include "absl/container/internal/hash_policy_testing.h"

namespace absl {
namespace container_internal {

template <class UnordSet>
class ModifiersTest : public ::testing::Test {};

TYPED_TEST_SUITE_P(ModifiersTest);

TYPED_TEST_P(ModifiersTest, Clear) {
  using T = hash_internal::GeneratedType<TypeParam>;
  std::vector<T> values;
  std::generate_n(std::back_inserter(values), 10,
                  hash_internal::Generator<T>());
  TypeParam m(values.begin(), values.end());
  ASSERT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
  m.clear();
  EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
  EXPECT_TRUE(m.empty());
}

TYPED_TEST_P(ModifiersTest, Insert) {
  using T = hash_internal::GeneratedType<TypeParam>;
  T val = hash_internal::Generator<T>()();
  TypeParam m;
  auto p = m.insert(val);
  EXPECT_TRUE(p.second);
  EXPECT_EQ(val, *p.first);
  p = m.insert(val);
  EXPECT_FALSE(p.second);
}

TYPED_TEST_P(ModifiersTest, InsertHint) {
  using T = hash_internal::GeneratedType<TypeParam>;
  T val = hash_internal::Generator<T>()();
  TypeParam m;
  auto it = m.insert(m.end(), val);
  EXPECT_TRUE(it != m.end());
  EXPECT_EQ(val, *it);
  it = m.insert(it, val);
  EXPECT_TRUE(it != m.end());
  EXPECT_EQ(val, *it);
}

TYPED_TEST_P(ModifiersTest, InsertRange) {
  using T = hash_internal::GeneratedType<TypeParam>;
  std::vector<T> values;
  std::generate_n(std::back_inserter(values), 10,
                  hash_internal::Generator<T>());
  TypeParam m;
  m.insert(values.begin(), values.end());
  ASSERT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
}

TYPED_TEST_P(ModifiersTest, Emplace) {
  using T = hash_internal::GeneratedType<TypeParam>;
  T val = hash_internal::Generator<T>()();
  TypeParam m;
  // TODO(alkis): We need a way to run emplace in a more meaningful way. Perhaps
  // with test traits/policy.
  auto p = m.emplace(val);
  EXPECT_TRUE(p.second);
  EXPECT_EQ(val, *p.first);
  p = m.emplace(val);
  EXPECT_FALSE(p.second);
  EXPECT_EQ(val, *p.first);
}

TYPED_TEST_P(ModifiersTest, EmplaceHint) {
  using T = hash_internal::GeneratedType<TypeParam>;
  T val = hash_internal::Generator<T>()();
  TypeParam m;
  // TODO(alkis): We need a way to run emplace in a more meaningful way. Perhaps
  // with test traits/policy.
  auto it = m.emplace_hint(m.end(), val);
  EXPECT_EQ(val, *it);
  it = m.emplace_hint(it, val);
  EXPECT_EQ(val, *it);
}

template <class V>
using IfNotVoid = typename std::enable_if<!std::is_void<V>::value, V>::type;

// In openmap we chose not to return the iterator from erase because that's
// more expensive. As such we adapt erase to return an iterator here.
struct EraseFirst {
  template <class Map>
  auto operator()(Map* m, int) const
      -> IfNotVoid<decltype(m->erase(m->begin()))> {
    return m->erase(m->begin());
  }
  template <class Map>
  typename Map::iterator operator()(Map* m, ...) const {
    auto it = m->begin();
    m->erase(it++);
    return it;
  }
};

TYPED_TEST_P(ModifiersTest, Erase) {
  using T = hash_internal::GeneratedType<TypeParam>;
  std::vector<T> values;
  std::generate_n(std::back_inserter(values), 10,
                  hash_internal::Generator<T>());
  TypeParam m(values.begin(), values.end());
  ASSERT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
  std::vector<T> values2;
  for (const auto& val : values)
    if (val != *m.begin()) values2.push_back(val);
  auto it = EraseFirst()(&m, 0);
  ASSERT_TRUE(it != m.end());
  EXPECT_EQ(1, std::count(values2.begin(), values2.end(), *it));
  EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values2.begin(),
                                                            values2.end()));
}

TYPED_TEST_P(ModifiersTest, EraseRange) {
  using T = hash_internal::GeneratedType<TypeParam>;
  std::vector<T> values;
  std::generate_n(std::back_inserter(values), 10,
                  hash_internal::Generator<T>());
  TypeParam m(values.begin(), values.end());
  ASSERT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
  auto it = m.erase(m.begin(), m.end());
  EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre());
  EXPECT_TRUE(it == m.end());
}

TYPED_TEST_P(ModifiersTest, EraseKey) {
  using T = hash_internal::GeneratedType<TypeParam>;
  std::vector<T> values;
  std::generate_n(std::back_inserter(values), 10,
                  hash_internal::Generator<T>());
  TypeParam m(values.begin(), values.end());
  ASSERT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values));
  EXPECT_EQ(1, m.erase(values[0]));
  EXPECT_EQ(0, std::count(m.begin(), m.end(), values[0]));
  EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values.begin() + 1,
                                                            values.end()));
}

TYPED_TEST_P(ModifiersTest, Swap) {
  using T = hash_internal::GeneratedType<TypeParam>;
  std::vector<T> v1;
  std::vector<T> v2;
  std::generate_n(std::back_inserter(v1), 5, hash_internal::Generator<T>());
  std::generate_n(std::back_inserter(v2), 5, hash_internal::Generator<T>());
  TypeParam m1(v1.begin(), v1.end());
  TypeParam m2(v2.begin(), v2.end());
  EXPECT_THAT(keys(m1), ::testing::UnorderedElementsAreArray(v1));
  EXPECT_THAT(keys(m2), ::testing::UnorderedElementsAreArray(v2));
  m1.swap(m2);
  EXPECT_THAT(keys(m1), ::testing::UnorderedElementsAreArray(v2));
  EXPECT_THAT(keys(m2), ::testing::UnorderedElementsAreArray(v1));
}

// TODO(alkis): Write tests for extract.
// TODO(alkis): Write tests for merge.

REGISTER_TYPED_TEST_CASE_P(ModifiersTest, Clear, Insert, InsertHint,
                           InsertRange, Emplace, EmplaceHint, Erase, EraseRange,
                           EraseKey, Swap);

}  // namespace container_internal
}  // namespace absl

#endif  // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MODIFIERS_TEST_H_
