// Copyright 2017 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
//
//      http://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/types/variant.h"

#include <iostream>
#include <memory>
#include <utility>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/internal/exception_safety_testing.h"
#include "absl/memory/memory.h"

namespace absl {
namespace {

using ::testing::MakeExceptionSafetyTester;
using ::testing::strong_guarantee;
using ::testing::TestNothrowOp;
using ::testing::TestThrowingCtor;

using Thrower = testing::ThrowingValue<>;
using CopyNothrow = testing::ThrowingValue<testing::TypeSpec::kNoThrowCopy>;
using MoveNothrow = testing::ThrowingValue<testing::TypeSpec::kNoThrowMove>;
using ThrowingAlloc = testing::ThrowingAllocator<Thrower>;
using ThrowerVec = std::vector<Thrower, ThrowingAlloc>;
using ThrowingVariant =
    absl::variant<Thrower, CopyNothrow, MoveNothrow, ThrowerVec>;

struct ConversionException {};

template <class T>
struct ExceptionOnConversion {
  operator T() const {  // NOLINT
    throw ConversionException();
  }
};

// Forces a variant into the valueless by exception state.
void ToValuelessByException(ThrowingVariant& v) {  // NOLINT
  try {
    v.emplace<Thrower>();
    v.emplace<Thrower>(ExceptionOnConversion<Thrower>());
  } catch (ConversionException& /*e*/) {
    // This space intentionally left blank.
  }
}

// Check that variant is still in a usable state after an exception is thrown.
testing::AssertionResult CheckInvariants(ThrowingVariant* v) {
  using testing::AssertionFailure;
  using testing::AssertionSuccess;

  // Try using the active alternative
  if (absl::holds_alternative<Thrower>(*v)) {
    auto& t = absl::get<Thrower>(*v);
    t = Thrower{-100};
    if (t.Get() != -100) {
      return AssertionFailure() << "Thrower should be assigned -100";
    }
  } else if (absl::holds_alternative<ThrowerVec>(*v)) {
    auto& tv = absl::get<ThrowerVec>(*v);
    tv.clear();
    tv.emplace_back(-100);
    if (tv.size() != 1 || tv[0].Get() != -100) {
      return AssertionFailure() << "ThrowerVec should be {Thrower{-100}}";
    }
  } else if (absl::holds_alternative<CopyNothrow>(*v)) {
    auto& t = absl::get<CopyNothrow>(*v);
    t = CopyNothrow{-100};
    if (t.Get() != -100) {
      return AssertionFailure() << "CopyNothrow should be assigned -100";
    }
  } else if (absl::holds_alternative<MoveNothrow>(*v)) {
    auto& t = absl::get<MoveNothrow>(*v);
    t = MoveNothrow{-100};
    if (t.Get() != -100) {
      return AssertionFailure() << "MoveNothrow should be assigned -100";
    }
  }

  // Try making variant valueless_by_exception
  if (!v->valueless_by_exception()) ToValuelessByException(*v);
  if (!v->valueless_by_exception()) {
    return AssertionFailure() << "Variant should be valueless_by_exception";
  }
  try {
    auto unused = absl::get<Thrower>(*v);
    static_cast<void>(unused);
    return AssertionFailure() << "Variant should not contain Thrower";
  } catch (absl::bad_variant_access) {
  } catch (...) {
    return AssertionFailure() << "Unexpected exception throw from absl::get";
  }

  // Try using the variant
  v->emplace<Thrower>(100);
  if (!absl::holds_alternative<Thrower>(*v) ||
      absl::get<Thrower>(*v) != Thrower(100)) {
    return AssertionFailure() << "Variant should contain Thrower(100)";
  }
  v->emplace<ThrowerVec>({Thrower(100)});
  if (!absl::holds_alternative<ThrowerVec>(*v) ||
      absl::get<ThrowerVec>(*v)[0] != Thrower(100)) {
    return AssertionFailure()
           << "Variant should contain ThrowerVec{Thrower(100)}";
  }
  return AssertionSuccess();
}

template <typename... Args>
Thrower ExpectedThrower(Args&&... args) {
  return Thrower(42, args...);
}

ThrowerVec ExpectedThrowerVec() { return {Thrower(100), Thrower(200)}; }
ThrowingVariant ValuelessByException() {
  ThrowingVariant v;
  ToValuelessByException(v);
  return v;
}
ThrowingVariant WithThrower() { return Thrower(39); }
ThrowingVariant WithThrowerVec() {
  return ThrowerVec{Thrower(1), Thrower(2), Thrower(3)};
}
ThrowingVariant WithCopyNoThrow() { return CopyNothrow(39); }
ThrowingVariant WithMoveNoThrow() { return MoveNothrow(39); }

TEST(VariantExceptionSafetyTest, DefaultConstructor) {
  TestThrowingCtor<ThrowingVariant>();
}

TEST(VariantExceptionSafetyTest, CopyConstructor) {
  {
    ThrowingVariant v(ExpectedThrower());
    TestThrowingCtor<ThrowingVariant>(v);
  }
  {
    ThrowingVariant v(ExpectedThrowerVec());
    TestThrowingCtor<ThrowingVariant>(v);
  }
  {
    ThrowingVariant v(ValuelessByException());
    TestThrowingCtor<ThrowingVariant>(v);
  }
}

TEST(VariantExceptionSafetyTest, MoveConstructor) {
  {
    ThrowingVariant v(ExpectedThrower());
    TestThrowingCtor<ThrowingVariant>(std::move(v));
  }
  {
    ThrowingVariant v(ExpectedThrowerVec());
    TestThrowingCtor<ThrowingVariant>(std::move(v));
  }
  {
    ThrowingVariant v(ValuelessByException());
    TestThrowingCtor<ThrowingVariant>(std::move(v));
  }
}

TEST(VariantExceptionSafetyTest, ValueConstructor) {
  TestThrowingCtor<ThrowingVariant>(ExpectedThrower());
  TestThrowingCtor<ThrowingVariant>(ExpectedThrowerVec());
}

TEST(VariantExceptionSafetyTest, InPlaceTypeConstructor) {
  TestThrowingCtor<ThrowingVariant>(absl::in_place_type_t<Thrower>{},
                                    ExpectedThrower());
  TestThrowingCtor<ThrowingVariant>(absl::in_place_type_t<ThrowerVec>{},
                                    ExpectedThrowerVec());
}

TEST(VariantExceptionSafetyTest, InPlaceIndexConstructor) {
  TestThrowingCtor<ThrowingVariant>(absl::in_place_index_t<0>{},
                                    ExpectedThrower());
  TestThrowingCtor<ThrowingVariant>(absl::in_place_index_t<3>{},
                                    ExpectedThrowerVec());
}

TEST(VariantExceptionSafetyTest, CopyAssign) {
  // variant& operator=(const variant& rhs);
  // Let j be rhs.index()
  {
    // - neither *this nor rhs holds a value
    const ThrowingVariant rhs = ValuelessByException();
    ThrowingVariant lhs = ValuelessByException();
    EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; }));
  }
  {
    // - *this holds a value but rhs does not
    const ThrowingVariant rhs = ValuelessByException();
    ThrowingVariant lhs = WithThrower();
    EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; }));
  }
  // - index() == j
  {
    const ThrowingVariant rhs(ExpectedThrower());
    auto tester =
        MakeExceptionSafetyTester()
            .WithInitialValue(WithThrower())
            .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
    EXPECT_TRUE(tester.WithInvariants(CheckInvariants).Test());
    EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
  }
  {
    const ThrowingVariant rhs(ExpectedThrowerVec());
    auto tester =
        MakeExceptionSafetyTester()
            .WithInitialValue(WithThrowerVec())
            .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
    EXPECT_TRUE(tester.WithInvariants(CheckInvariants).Test());
    EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
  }
  // libstdc++ std::variant has bugs on copy assignment regarding exception
  // safety.
#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__))
  // index() != j
  // if is_nothrow_copy_constructible_v<Tj> or
  // !is_nothrow_move_constructible<Tj> is true, equivalent to
  // emplace<j>(get<j>(rhs))
  {
    // is_nothrow_copy_constructible_v<Tj> == true
    // should not throw because emplace() invokes Tj's copy ctor
    // which should not throw.
    const ThrowingVariant rhs(CopyNothrow{});
    ThrowingVariant lhs = WithThrower();
    EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; }));
  }
  {
    // is_nothrow_copy_constructible<Tj> == false &&
    // is_nothrow_move_constructible<Tj> == false
    // should provide basic guarantee because emplace() invokes Tj's copy ctor
    // which may throw.
    const ThrowingVariant rhs(ExpectedThrower());
    auto tester =
        MakeExceptionSafetyTester()
            .WithInitialValue(WithCopyNoThrow())
            .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
    EXPECT_TRUE(tester
                    .WithInvariants(CheckInvariants,
                                    [](ThrowingVariant* lhs) {
                                      return lhs->valueless_by_exception();
                                    })
                    .Test());
    EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
  }
#endif  // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__))
  {
    // is_nothrow_copy_constructible_v<Tj> == false &&
    // is_nothrow_move_constructible_v<Tj> == true
    // should provide strong guarantee because it is equivalent to
    // operator=(variant(rhs)) which creates a temporary then invoke the move
    // ctor which shouldn't throw.
    const ThrowingVariant rhs(MoveNothrow{});
    EXPECT_TRUE(MakeExceptionSafetyTester()
                    .WithInitialValue(WithThrower())
                    .WithInvariants(CheckInvariants, strong_guarantee)
                    .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }));
  }
}

TEST(VariantExceptionSafetyTest, MoveAssign) {
  // variant& operator=(variant&& rhs);
  // Let j be rhs.index()
  {
    // - neither *this nor rhs holds a value
    ThrowingVariant rhs = ValuelessByException();
    ThrowingVariant lhs = ValuelessByException();
    EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); }));
  }
  {
    // - *this holds a value but rhs does not
    ThrowingVariant rhs = ValuelessByException();
    ThrowingVariant lhs = WithThrower();
    EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); }));
  }
  {
    // - index() == j
    // assign get<j>(std::move(rhs)) to the value contained in *this.
    // If an exception is thrown during call to Tj's move assignment, the state
    // of the contained value is as defined by the exception safety guarantee of
    // Tj's move assignment; index() will be j.
    ThrowingVariant rhs(ExpectedThrower());
    size_t j = rhs.index();
    // Since Thrower's move assignment has basic guarantee, so should variant's.
    auto tester = MakeExceptionSafetyTester()
                      .WithInitialValue(WithThrower())
                      .WithOperation([&](ThrowingVariant* lhs) {
                        auto copy = rhs;
                        *lhs = std::move(copy);
                      });
    EXPECT_TRUE(tester
                    .WithInvariants(
                        CheckInvariants,
                        [&](ThrowingVariant* lhs) { return lhs->index() == j; })
                    .Test());
    EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
  }
  {
    // - otherwise (index() != j), equivalent to
    // emplace<j>(get<j>(std::move(rhs)))
    // - If an exception is thrown during the call to Tj's move construction
    // (with j being rhs.index()), the variant will hold no value.
    ThrowingVariant rhs(CopyNothrow{});
    EXPECT_TRUE(MakeExceptionSafetyTester()
                    .WithInitialValue(WithThrower())
                    .WithInvariants(CheckInvariants,
                                    [](ThrowingVariant* lhs) {
                                      return lhs->valueless_by_exception();
                                    })
                    .Test([&](ThrowingVariant* lhs) {
                      auto copy = rhs;
                      *lhs = std::move(copy);
                    }));
  }
}

TEST(VariantExceptionSafetyTest, ValueAssign) {
  // template<class T> variant& operator=(T&& t);
  // Let Tj be the type that is selected by overload resolution to be assigned.
  {
    // If *this holds a Tj, assigns std::forward<T>(t) to the value contained in
    // *this. If  an exception is thrown during the assignment of
    // std::forward<T>(t) to the value contained in *this, the state of the
    // contained value and t are as defined by the exception safety guarantee of
    // the assignment expression; valueless_by_exception() will be false.
    // Since Thrower's copy/move assignment has basic guarantee, so should
    // variant's.
    Thrower rhs = ExpectedThrower();
    // copy assign
    auto copy_tester =
        MakeExceptionSafetyTester()
            .WithInitialValue(WithThrower())
            .WithOperation([rhs](ThrowingVariant* lhs) { *lhs = rhs; });
    EXPECT_TRUE(copy_tester
                    .WithInvariants(CheckInvariants,
                                    [](ThrowingVariant* lhs) {
                                      return !lhs->valueless_by_exception();
                                    })
                    .Test());
    EXPECT_FALSE(copy_tester.WithInvariants(strong_guarantee).Test());
    // move assign
    auto move_tester = MakeExceptionSafetyTester()
                           .WithInitialValue(WithThrower())
                           .WithOperation([&](ThrowingVariant* lhs) {
                             auto copy = rhs;
                             *lhs = std::move(copy);
                           });
    EXPECT_TRUE(move_tester
                    .WithInvariants(CheckInvariants,
                                    [](ThrowingVariant* lhs) {
                                      return !lhs->valueless_by_exception();
                                    })
                    .Test());

    EXPECT_FALSE(move_tester.WithInvariants(strong_guarantee).Test());
  }
  // Otherwise (*this holds something else), if is_nothrow_constructible_v<Tj,
  // T> || !is_nothrow_move_constructible_v<Tj> is true, equivalent to
  // emplace<j>(std::forward<T>(t)).
  // We simplify the test by letting T = `const Tj&`  or `Tj&&`, so we can reuse
  // the CopyNothrow and MoveNothrow types.

  // if is_nothrow_constructible_v<Tj, T>
  // (i.e. is_nothrow_copy/move_constructible_v<Tj>) is true, emplace() just
  // invokes the copy/move constructor and it should not throw.
  {
    const CopyNothrow rhs;
    ThrowingVariant lhs = WithThrower();
    EXPECT_TRUE(TestNothrowOp([&]() { lhs = rhs; }));
  }
  {
    MoveNothrow rhs;
    ThrowingVariant lhs = WithThrower();
    EXPECT_TRUE(TestNothrowOp([&]() { lhs = std::move(rhs); }));
  }
  // if is_nothrow_constructible_v<Tj, T> == false &&
  // is_nothrow_move_constructible<Tj> == false
  // emplace() invokes the copy/move constructor which may throw so it should
  // provide basic guarantee and variant object might not hold a value.
  {
    Thrower rhs = ExpectedThrower();
    // copy
    auto copy_tester =
        MakeExceptionSafetyTester()
            .WithInitialValue(WithCopyNoThrow())
            .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
    EXPECT_TRUE(copy_tester
                    .WithInvariants(CheckInvariants,
                                    [](ThrowingVariant* lhs) {
                                      return lhs->valueless_by_exception();
                                    })
                    .Test());
    EXPECT_FALSE(copy_tester.WithInvariants(strong_guarantee).Test());
    // move
    auto move_tester = MakeExceptionSafetyTester()
                           .WithInitialValue(WithCopyNoThrow())
                           .WithOperation([](ThrowingVariant* lhs) {
                             *lhs = ExpectedThrower(testing::nothrow_ctor);
                           });
    EXPECT_TRUE(move_tester
                    .WithInvariants(CheckInvariants,
                                    [](ThrowingVariant* lhs) {
                                      return lhs->valueless_by_exception();
                                    })
                    .Test());
    EXPECT_FALSE(move_tester.WithInvariants(strong_guarantee).Test());
  }
  // Otherwise (if is_nothrow_constructible_v<Tj, T> == false &&
  // is_nothrow_move_constructible<Tj> == true),
  // equivalent to operator=(variant(std::forward<T>(t)))
  // This should have strong guarantee because it creates a temporary variant
  // and operator=(variant&&) invokes Tj's move ctor which doesn't throw.
  // libstdc++ std::variant has bugs on conversion assignment regarding
  // exception safety.
#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__))
  {
    MoveNothrow rhs;
    EXPECT_TRUE(MakeExceptionSafetyTester()
                    .WithInitialValue(WithThrower())
                    .WithInvariants(CheckInvariants, strong_guarantee)
                    .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; }));
  }
#endif  // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__))
}

TEST(VariantExceptionSafetyTest, Emplace) {
  // If an exception during the initialization of the contained value, the
  // variant might not hold a value. The standard requires emplace() to provide
  // only basic guarantee.
  {
    Thrower args = ExpectedThrower();
    auto tester = MakeExceptionSafetyTester()
                      .WithInitialValue(WithThrower())
                      .WithOperation([&args](ThrowingVariant* v) {
                        v->emplace<Thrower>(args);
                      });
    EXPECT_TRUE(tester
                    .WithInvariants(CheckInvariants,
                                    [](ThrowingVariant* v) {
                                      return v->valueless_by_exception();
                                    })
                    .Test());
    EXPECT_FALSE(tester.WithInvariants(strong_guarantee).Test());
  }
}

TEST(VariantExceptionSafetyTest, Swap) {
  // if both are valueless_by_exception(), no effect
  {
    ThrowingVariant rhs = ValuelessByException();
    ThrowingVariant lhs = ValuelessByException();
    EXPECT_TRUE(TestNothrowOp([&]() { lhs.swap(rhs); }));
  }
  // if index() == rhs.index(), calls swap(get<i>(*this), get<i>(rhs))
  // where i is index().
  {
    ThrowingVariant rhs = ExpectedThrower();
    EXPECT_TRUE(MakeExceptionSafetyTester()
                    .WithInitialValue(WithThrower())
                    .WithInvariants(CheckInvariants)
                    .Test([&](ThrowingVariant* lhs) {
                      auto copy = rhs;
                      lhs->swap(copy);
                    }));
  }
  // Otherwise, exchanges the value of rhs and *this. The exception safety
  // involves variant in moved-from state which is not specified in the
  // standard, and since swap is 3-step it's impossible for it to provide a
  // overall strong guarantee. So, we are only checking basic guarantee here.
  {
    ThrowingVariant rhs = ExpectedThrower();
    EXPECT_TRUE(MakeExceptionSafetyTester()
                    .WithInitialValue(WithCopyNoThrow())
                    .WithInvariants(CheckInvariants)
                    .Test([&](ThrowingVariant* lhs) {
                      auto copy = rhs;
                      lhs->swap(copy);
                    }));
  }
  {
    ThrowingVariant rhs = ExpectedThrower();
    EXPECT_TRUE(MakeExceptionSafetyTester()
                    .WithInitialValue(WithCopyNoThrow())
                    .WithInvariants(CheckInvariants)
                    .Test([&](ThrowingVariant* lhs) {
                      auto copy = rhs;
                      copy.swap(*lhs);
                    }));
  }
}

}  // namespace
}  // namespace absl
