// Copyright 2026 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/functional/bind_back.h"

#include <stddef.h>

#include <functional>
#include <memory>
#include <string>
#include <utility>

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

namespace {

char CharAt(const char* s, size_t index) { return s[index]; }

TEST(BindTest, Basics) {
  EXPECT_EQ('C', absl::bind_back(CharAt)("ABC", 2));
  EXPECT_EQ('C', absl::bind_back(CharAt, 2)("ABC"));
  EXPECT_EQ('C', absl::bind_back(CharAt, "ABC", 2)());
}

TEST(BindTest, Lambda) {
  auto lambda = [](int x, int y, int z) { return x + y + z; };
  EXPECT_EQ(6, absl::bind_back(lambda)(1, 2, 3));
  EXPECT_EQ(6, absl::bind_back(lambda, 3)(1, 2));
  EXPECT_EQ(6, absl::bind_back(lambda, 2, 3)(1));
  EXPECT_EQ(6, absl::bind_back(lambda, 1, 2, 3)());
}

struct Functor {
  std::string operator()() & { return "&"; }
  std::string operator()() const& { return "const&"; }
  std::string operator()() && { return "&&"; }
  std::string operator()() const&& { return "const&&"; }
};

TEST(BindTest, PerfectForwardingOfBoundArgs) {
  auto f = absl::bind_back(Functor());
  const auto& cf = f;
  EXPECT_EQ("&", f());
  EXPECT_EQ("const&", cf());
  EXPECT_EQ("&&", std::move(f)());
  EXPECT_EQ("const&&", std::move(cf)());
}

struct ArgDescribe {
  std::string operator()(int&) const { return "&"; }             // NOLINT
  std::string operator()(const int&) const { return "const&"; }  // NOLINT
  std::string operator()(int&&) const { return "&&"; }
  std::string operator()(const int&&) const { return "const&&"; }
};

TEST(BindTest, PerfectForwardingOfFreeArgs) {
  ArgDescribe f;
  int i;
  EXPECT_EQ("&", absl::bind_back(f)(static_cast<int&>(i)));
  EXPECT_EQ("const&", absl::bind_back(f)(static_cast<const int&>(i)));
  EXPECT_EQ("&&", absl::bind_back(f)(static_cast<int&&>(i)));
  EXPECT_EQ("const&&", absl::bind_back(f)(static_cast<const int&&>(i)));
}

struct NonCopyableFunctor {
  NonCopyableFunctor() = default;
  NonCopyableFunctor(const NonCopyableFunctor&) = delete;
  NonCopyableFunctor& operator=(const NonCopyableFunctor&) = delete;
  const NonCopyableFunctor* operator()() const { return this; }
};

TEST(BindTest, RefToFunctor) {
  // It won't copy/move the functor and use the original object.
  NonCopyableFunctor ncf;
  auto bound_ncf = absl::bind_back(std::ref(ncf));
  auto bound_ncf_copy = bound_ncf;
  EXPECT_EQ(&ncf, bound_ncf_copy());
}

struct Struct {
  std::string value;
};

TEST(BindTest, StoreByCopy) {
  Struct s = {"hello"};
  auto f = absl::bind_back(&Struct::value, s);
  auto g = f;
  EXPECT_EQ("hello", f());
  EXPECT_EQ("hello", g());
  EXPECT_NE(&s.value, &f());
  EXPECT_NE(&s.value, &g());
  EXPECT_NE(&g(), &f());
}

struct NonCopyable {
  explicit NonCopyable(const std::string& s) : value(s) {}
  NonCopyable(const NonCopyable&) = delete;
  NonCopyable& operator=(const NonCopyable&) = delete;

  std::string value;
};

const std::string& GetNonCopyableValue(const NonCopyable& n) { return n.value; }

TEST(BindTest, StoreByRef) {
  NonCopyable s("hello");
  auto f = absl::bind_back(&GetNonCopyableValue, std::ref(s));
  EXPECT_EQ("hello", f());
  EXPECT_EQ(&s.value, &f());
  auto g = std::move(f);  // NOLINT
  EXPECT_EQ("hello", g());
  EXPECT_EQ(&s.value, &g());
  s.value = "goodbye";
  EXPECT_EQ("goodbye", g());
}

TEST(BindTest, StoreByCRef) {
  NonCopyable s("hello");
  auto f = absl::bind_back(&GetNonCopyableValue, std::cref(s));
  EXPECT_EQ("hello", f());
  EXPECT_EQ(&s.value, &f());
  auto g = std::move(f);  // NOLINT
  EXPECT_EQ("hello", g());
  EXPECT_EQ(&s.value, &g());
  s.value = "goodbye";
  EXPECT_EQ("goodbye", g());
}

const std::string& GetNonCopyableValueByWrapper(
    std::reference_wrapper<NonCopyable> n) {
  return n.get().value;
}

TEST(BindTest, StoreByRefInvokeByWrapper) {
  NonCopyable s("hello");
  auto f = absl::bind_back(GetNonCopyableValueByWrapper, std::ref(s));
  EXPECT_EQ("hello", f());
  EXPECT_EQ(&s.value, &f());
  auto g = std::move(f);
  EXPECT_EQ("hello", g());
  EXPECT_EQ(&s.value, &g());
  s.value = "goodbye";
  EXPECT_EQ("goodbye", g());
}

TEST(BindTest, StoreByPointer) {
  NonCopyable s("hello");
  auto f = absl::bind_back(&NonCopyable::value, &s);
  EXPECT_EQ("hello", f());
  EXPECT_EQ(&s.value, &f());
  auto g = std::move(f);
  EXPECT_EQ("hello", g());
  EXPECT_EQ(&s.value, &g());
}

struct MyStruct {
  int x;
  int Add(int y) const { return x + y; }
};

TEST(BindTest, MemberFunctionFreeInstance) {
  MyStruct s{10};
  auto f = absl::bind_back(&MyStruct::Add, 5);
  EXPECT_EQ(f(s), 15);
}

int Sink(std::unique_ptr<int> p) { return *p; }

std::unique_ptr<int> Factory(int n) { return std::make_unique<int>(n); }

TEST(BindTest, NonCopyableArg) {
  EXPECT_EQ(42, absl::bind_back(Sink)(std::make_unique<int>(42)));
  EXPECT_EQ(42, absl::bind_back(Sink, std::make_unique<int>(42))());
}

TEST(BindTest, NonCopyableResult) {
  EXPECT_THAT(absl::bind_back(Factory)(42), ::testing::Pointee(42));
  EXPECT_THAT(absl::bind_back(Factory, 42)(), ::testing::Pointee(42));
}

// is_copy_constructible<FalseCopyable<unique_ptr<T>> is true but an attempt to
// instantiate the copy constructor leads to a compile error. This is similar
// to how standard containers behave.
template <class T>
struct FalseCopyable {
  FalseCopyable() = default;
  FalseCopyable(const FalseCopyable& other) : m(other.m) {}
  FalseCopyable(FalseCopyable&& other) : m(std::move(other.m)) {}
  T m;
};

int GetMember(FalseCopyable<std::unique_ptr<int>> x) { return *x.m; }

TEST(BindTest, WrappedMoveOnly) {
  FalseCopyable<std::unique_ptr<int>> x;
  x.m = std::make_unique<int>(42);
  auto f = absl::bind_back(&GetMember, std::move(x));
  EXPECT_EQ(42, std::move(f)());
}

int Plus(int a, int b) { return a + b; }

TEST(BindTest, ConstExpr) {
  constexpr auto f = absl::bind_back(CharAt);
  EXPECT_EQ(f("ABC", 1), 'B');
  static constexpr int five = 5;
  constexpr auto plus5 = absl::bind_back(Plus, five);
  EXPECT_EQ(plus5(1), 6);

  static constexpr char data[] = "DEF";
  constexpr auto g = absl::bind_back(CharAt, 1);
  EXPECT_EQ(g(data), 'E');
}

struct ManglingCall {
  int operator()(int, double, std::string) const { return 0; }
};

TEST(BindTest, Mangling) {
  // We just want to generate a particular instantiation to see its mangling.
  absl::bind_back(ManglingCall{}, 3.3, "A")(1);
}

}  // namespace
