// 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/config.h"
#include "absl/base/internal/exception_safety_testing.h"
#include "absl/memory/memory.h"
// See comment in absl/base/config.h
#if !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE)

namespace absl {
inline namespace lts_2018_12_18 {
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 (const ConversionException&) {
    // This space intentionally left blank.
  }
}

// Check that variant is still in a usable state after an exception is thrown.
testing::AssertionResult VariantInvariants(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 (const 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.WithContracts(VariantInvariants).Test());
    EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test());
  }
  {
    const ThrowingVariant rhs(ExpectedThrowerVec());
    auto tester =
        MakeExceptionSafetyTester()
            .WithInitialValue(WithThrowerVec())
            .WithOperation([&rhs](ThrowingVariant* lhs) { *lhs = rhs; });
    EXPECT_TRUE(tester.WithContracts(VariantInvariants).Test());
    EXPECT_FALSE(tester.WithContracts(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
                    .WithContracts(VariantInvariants,
                                   [](ThrowingVariant* lhs) {
                                     return lhs->valueless_by_exception();
                                   })
                    .Test());
    EXPECT_FALSE(tester.WithContracts(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())
                    .WithContracts(VariantInvariants, 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
                    .WithContracts(
                        VariantInvariants,
                        [&](ThrowingVariant* lhs) { return lhs->index() == j; })
                    .Test());
    EXPECT_FALSE(tester.WithContracts(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())
                    .WithContracts(VariantInvariants,
                                   [](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
                    .WithContracts(VariantInvariants,
                                   [](ThrowingVariant* lhs) {
                                     return !lhs->valueless_by_exception();
                                   })
                    .Test());
    EXPECT_FALSE(copy_tester.WithContracts(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
                    .WithContracts(VariantInvariants,
                                   [](ThrowingVariant* lhs) {
                                     return !lhs->valueless_by_exception();
                                   })
                    .Test());

    EXPECT_FALSE(move_tester.WithContracts(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
                    .WithContracts(VariantInvariants,
                                   [](ThrowingVariant* lhs) {
                                     return lhs->valueless_by_exception();
                                   })
                    .Test());
    EXPECT_FALSE(copy_tester.WithContracts(strong_guarantee).Test());
    // move
    auto move_tester = MakeExceptionSafetyTester()
                           .WithInitialValue(WithCopyNoThrow())
                           .WithOperation([](ThrowingVariant* lhs) {
                             *lhs = ExpectedThrower(testing::nothrow_ctor);
                           });
    EXPECT_TRUE(move_tester
                    .WithContracts(VariantInvariants,
                                   [](ThrowingVariant* lhs) {
                                     return lhs->valueless_by_exception();
                                   })
                    .Test());
    EXPECT_FALSE(move_tester.WithContracts(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())
                    .WithContracts(VariantInvariants, 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
                    .WithContracts(VariantInvariants,
                                   [](ThrowingVariant* v) {
                                     return v->valueless_by_exception();
                                   })
                    .Test());
    EXPECT_FALSE(tester.WithContracts(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())
                    .WithContracts(VariantInvariants)
                    .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())
                    .WithContracts(VariantInvariants)
                    .Test([&](ThrowingVariant* lhs) {
                      auto copy = rhs;
                      lhs->swap(copy);
                    }));
  }
  {
    ThrowingVariant rhs = ExpectedThrower();
    EXPECT_TRUE(MakeExceptionSafetyTester()
                    .WithInitialValue(WithCopyNoThrow())
                    .WithContracts(VariantInvariants)
                    .Test([&](ThrowingVariant* lhs) {
                      auto copy = rhs;
                      copy.swap(*lhs);
                    }));
  }
}

}  // namespace
}  // inline namespace lts_2018_12_18
}  // namespace absl

#endif  // !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE)
