//===- llvm/Testing/Support/Error.h ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TESTING_SUPPORT_ERROR_H
#define LLVM_TESTING_SUPPORT_ERROR_H

#include "llvm/ADT/Optional.h"
#include "llvm/Support/Error.h"
#include "llvm/Testing/Support/SupportHelpers.h"

#include "gmock/gmock.h"
#include <ostream>

namespace llvm {
namespace detail {
ErrorHolder TakeError(Error Err);

template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &Exp) {
  return {TakeError(Exp.takeError()), Exp};
}

template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) {
  return TakeExpected(Exp);
}

template <typename T>
class ValueMatchesMono
    : public testing::MatcherInterface<const ExpectedHolder<T> &> {
public:
  explicit ValueMatchesMono(const testing::Matcher<T> &Matcher)
      : Matcher(Matcher) {}

  bool MatchAndExplain(const ExpectedHolder<T> &Holder,
                       testing::MatchResultListener *listener) const override {
    if (!Holder.Success())
      return false;

    bool result = Matcher.MatchAndExplain(*Holder.Exp, listener);

    if (result || !listener->IsInterested())
      return result;
    *listener << "(";
    Matcher.DescribeNegationTo(listener->stream());
    *listener << ")";
    return result;
  }

  void DescribeTo(std::ostream *OS) const override {
    *OS << "succeeded with value (";
    Matcher.DescribeTo(OS);
    *OS << ")";
  }

  void DescribeNegationTo(std::ostream *OS) const override {
    *OS << "did not succeed or value (";
    Matcher.DescribeNegationTo(OS);
    *OS << ")";
  }

private:
  testing::Matcher<T> Matcher;
};

template<typename M>
class ValueMatchesPoly {
public:
  explicit ValueMatchesPoly(const M &Matcher) : Matcher(Matcher) {}

  template <typename T>
  operator testing::Matcher<const ExpectedHolder<T> &>() const {
    return MakeMatcher(
        new ValueMatchesMono<T>(testing::SafeMatcherCast<T>(Matcher)));
  }

private:
  M Matcher;
};

template <typename InfoT>
class ErrorMatchesMono : public testing::MatcherInterface<const ErrorHolder &> {
public:
  explicit ErrorMatchesMono(Optional<testing::Matcher<InfoT &>> Matcher)
      : Matcher(std::move(Matcher)) {}

  bool MatchAndExplain(const ErrorHolder &Holder,
                       testing::MatchResultListener *listener) const override {
    if (Holder.Success())
      return false;

    if (Holder.Infos.size() > 1) {
      *listener << "multiple errors";
      return false;
    }

    auto &Info = *Holder.Infos[0];
    if (!Info.isA<InfoT>()) {
      *listener << "Error was not of given type";
      return false;
    }

    if (!Matcher)
      return true;

    return Matcher->MatchAndExplain(static_cast<InfoT &>(Info), listener);
  }

  void DescribeTo(std::ostream *OS) const override {
    *OS << "failed with Error of given type";
    if (Matcher) {
      *OS << " and the error ";
      Matcher->DescribeTo(OS);
    }
  }

  void DescribeNegationTo(std::ostream *OS) const override {
    *OS << "succeeded or did not fail with the error of given type";
    if (Matcher) {
      *OS << " or the error ";
      Matcher->DescribeNegationTo(OS);
    }
  }

private:
  Optional<testing::Matcher<InfoT &>> Matcher;
};

class ErrorMessageMatches
    : public testing::MatcherInterface<const ErrorHolder &> {
public:
  explicit ErrorMessageMatches(
      testing::Matcher<std::vector<std::string>> Matcher)
      : Matcher(std::move(Matcher)) {}

  bool MatchAndExplain(const ErrorHolder &Holder,
                       testing::MatchResultListener *listener) const override {
    std::vector<std::string> Messages;
    for (const std::shared_ptr<ErrorInfoBase> &Info: Holder.Infos)
      Messages.push_back(Info->message());

    return Matcher.MatchAndExplain(Messages, listener);
  }

  void DescribeTo(std::ostream *OS) const override {
    *OS << "failed with Error whose message ";
    Matcher.DescribeTo(OS);
  }

  void DescribeNegationTo(std::ostream *OS) const override {
    *OS << "failed with an Error whose message ";
    Matcher.DescribeNegationTo(OS);
  }

private:
  testing::Matcher<std::vector<std::string>> Matcher;
};
} // namespace detail

#define EXPECT_THAT_ERROR(Err, Matcher)                                        \
  EXPECT_THAT(llvm::detail::TakeError(Err), Matcher)
#define ASSERT_THAT_ERROR(Err, Matcher)                                        \
  ASSERT_THAT(llvm::detail::TakeError(Err), Matcher)

/// Helper macro for checking the result of an 'Expected<T>'
///
///   @code{.cpp}
///     // function to be tested
///     Expected<int> myDivide(int A, int B);
///
///     TEST(myDivideTests, GoodAndBad) {
///       // test good case
///       // if you only care about success or failure:
///       EXPECT_THAT_EXPECTED(myDivide(10, 5), Succeeded());
///       // if you also care about the value:
///       EXPECT_THAT_EXPECTED(myDivide(10, 5), HasValue(2));
///
///       // test the error case
///       EXPECT_THAT_EXPECTED(myDivide(10, 0), Failed());
///       // also check the error message
///       EXPECT_THAT_EXPECTED(myDivide(10, 0),
///           FailedWithMessage("B must not be zero!"));
///     }
///   @endcode

#define EXPECT_THAT_EXPECTED(Err, Matcher)                                     \
  EXPECT_THAT(llvm::detail::TakeExpected(Err), Matcher)
#define ASSERT_THAT_EXPECTED(Err, Matcher)                                     \
  ASSERT_THAT(llvm::detail::TakeExpected(Err), Matcher)

MATCHER(Succeeded, "") { return arg.Success(); }
MATCHER(Failed, "") { return !arg.Success(); }

template <typename InfoT>
testing::Matcher<const detail::ErrorHolder &> Failed() {
  return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(None));
}

template <typename InfoT, typename M>
testing::Matcher<const detail::ErrorHolder &> Failed(M Matcher) {
  return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(
      testing::SafeMatcherCast<InfoT &>(Matcher)));
}

template <typename... M>
testing::Matcher<const detail::ErrorHolder &> FailedWithMessage(M... Matcher) {
  static_assert(sizeof...(M) > 0, "");
  return MakeMatcher(
      new detail::ErrorMessageMatches(testing::ElementsAre(Matcher...)));
}

template <typename M>
testing::Matcher<const detail::ErrorHolder &> FailedWithMessageArray(M Matcher) {
  return MakeMatcher(new detail::ErrorMessageMatches(Matcher));
}

template <typename M>
detail::ValueMatchesPoly<M> HasValue(M Matcher) {
  return detail::ValueMatchesPoly<M>(Matcher);
}

} // namespace llvm

#endif
