// 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/internal/hash_policy_traits.h"

#include <functional>
#include <memory>
#include <new>

#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace absl {
inline namespace lts_2019_08_08 {
namespace container_internal {
namespace {

using ::testing::MockFunction;
using ::testing::Return;
using ::testing::ReturnRef;

using Alloc = std::allocator<int>;
using Slot = int;

struct PolicyWithoutOptionalOps {
  using slot_type = Slot;
  using key_type = Slot;
  using init_type = Slot;

  static std::function<void(void*, Slot*, Slot)> construct;
  static std::function<void(void*, Slot*)> destroy;

  static std::function<Slot&(Slot*)> element;
  static int apply(int v) { return apply_impl(v); }
  static std::function<int(int)> apply_impl;
  static std::function<Slot&(Slot*)> value;
};

std::function<void(void*, Slot*, Slot)> PolicyWithoutOptionalOps::construct;
std::function<void(void*, Slot*)> PolicyWithoutOptionalOps::destroy;

std::function<Slot&(Slot*)> PolicyWithoutOptionalOps::element;
std::function<int(int)> PolicyWithoutOptionalOps::apply_impl;
std::function<Slot&(Slot*)> PolicyWithoutOptionalOps::value;

struct PolicyWithOptionalOps : PolicyWithoutOptionalOps {
  static std::function<void(void*, Slot*, Slot*)> transfer;
};

std::function<void(void*, Slot*, Slot*)> PolicyWithOptionalOps::transfer;

struct Test : ::testing::Test {
  Test() {
    PolicyWithoutOptionalOps::construct = [&](void* a1, Slot* a2, Slot a3) {
      construct.Call(a1, a2, std::move(a3));
    };
    PolicyWithoutOptionalOps::destroy = [&](void* a1, Slot* a2) {
      destroy.Call(a1, a2);
    };

    PolicyWithoutOptionalOps::element = [&](Slot* a1) -> Slot& {
      return element.Call(a1);
    };
    PolicyWithoutOptionalOps::apply_impl = [&](int a1) -> int {
      return apply.Call(a1);
    };
    PolicyWithoutOptionalOps::value = [&](Slot* a1) -> Slot& {
      return value.Call(a1);
    };

    PolicyWithOptionalOps::transfer = [&](void* a1, Slot* a2, Slot* a3) {
      return transfer.Call(a1, a2, a3);
    };
  }

  std::allocator<int> alloc;
  int a = 53;

  MockFunction<void(void*, Slot*, Slot)> construct;
  MockFunction<void(void*, Slot*)> destroy;

  MockFunction<Slot&(Slot*)> element;
  MockFunction<int(int)> apply;
  MockFunction<Slot&(Slot*)> value;

  MockFunction<void(void*, Slot*, Slot*)> transfer;
};

TEST_F(Test, construct) {
  EXPECT_CALL(construct, Call(&alloc, &a, 53));
  hash_policy_traits<PolicyWithoutOptionalOps>::construct(&alloc, &a, 53);
}

TEST_F(Test, destroy) {
  EXPECT_CALL(destroy, Call(&alloc, &a));
  hash_policy_traits<PolicyWithoutOptionalOps>::destroy(&alloc, &a);
}

TEST_F(Test, element) {
  int b = 0;
  EXPECT_CALL(element, Call(&a)).WillOnce(ReturnRef(b));
  EXPECT_EQ(&b, &hash_policy_traits<PolicyWithoutOptionalOps>::element(&a));
}

TEST_F(Test, apply) {
  EXPECT_CALL(apply, Call(42)).WillOnce(Return(1337));
  EXPECT_EQ(1337, (hash_policy_traits<PolicyWithoutOptionalOps>::apply(42)));
}

TEST_F(Test, value) {
  int b = 0;
  EXPECT_CALL(value, Call(&a)).WillOnce(ReturnRef(b));
  EXPECT_EQ(&b, &hash_policy_traits<PolicyWithoutOptionalOps>::value(&a));
}

TEST_F(Test, without_transfer) {
  int b = 42;
  EXPECT_CALL(element, Call(&b)).WillOnce(::testing::ReturnRef(b));
  EXPECT_CALL(construct, Call(&alloc, &a, b));
  EXPECT_CALL(destroy, Call(&alloc, &b));
  hash_policy_traits<PolicyWithoutOptionalOps>::transfer(&alloc, &a, &b);
}

TEST_F(Test, with_transfer) {
  int b = 42;
  EXPECT_CALL(transfer, Call(&alloc, &a, &b));
  hash_policy_traits<PolicyWithOptionalOps>::transfer(&alloc, &a, &b);
}

}  // namespace
}  // namespace container_internal
}  // inline namespace lts_2019_08_08
}  // namespace absl
