//===-- Matchers.h ----------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// GMock matchers that aren't specific to particular tests.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_MATCHERS_H
#define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_MATCHERS_H
#include "Protocol.h"
#include "gmock/gmock.h"

namespace clang {
namespace clangd {
using ::testing::Matcher;

// EXPECT_IFF expects matcher if condition is true, and Not(matcher) if false.
// This is hard to write as a function, because matchers may be polymorphic.
#define EXPECT_IFF(condition, value, matcher)                                  \
  do {                                                                         \
    if (condition)                                                             \
      EXPECT_THAT(value, matcher);                                             \
    else                                                                       \
      EXPECT_THAT(value, ::testing::Not(matcher));                             \
  } while (0)

// HasSubsequence(m1, m2, ...) matches a vector containing elements that match
// m1, m2 ... in that order.
//
// SubsequenceMatcher implements this once the type of vector is known.
template <typename T>
class SubsequenceMatcher
    : public ::testing::MatcherInterface<const std::vector<T> &> {
  std::vector<Matcher<T>> Matchers;

public:
  SubsequenceMatcher(std::vector<Matcher<T>> M) : Matchers(M) {}

  void DescribeTo(std::ostream *OS) const override {
    *OS << "Contains the subsequence [";
    const char *Sep = "";
    for (const auto &M : Matchers) {
      *OS << Sep;
      M.DescribeTo(OS);
      Sep = ", ";
    }
    *OS << "]";
  }

  bool MatchAndExplain(const std::vector<T> &V,
                       ::testing::MatchResultListener *L) const override {
    std::vector<int> Matches(Matchers.size());
    size_t I = 0;
    for (size_t J = 0; I < Matchers.size() && J < V.size(); ++J)
      if (Matchers[I].Matches(V[J]))
        Matches[I++] = J;
    if (I == Matchers.size()) // We exhausted all matchers.
      return true;
    if (L->IsInterested()) {
      *L << "\n  Matched:";
      for (size_t K = 0; K < I; ++K) {
        *L << "\n\t";
        Matchers[K].DescribeTo(L->stream());
        *L << " ==> " << ::testing::PrintToString(V[Matches[K]]);
      }
      *L << "\n\t";
      Matchers[I].DescribeTo(L->stream());
      *L << " ==> no subsequent match";
    }
    return false;
  }
};

// PolySubsequenceMatcher implements a "polymorphic" SubsequenceMatcher.
// It captures the types of the element matchers, and can be converted to
// Matcher<vector<T>> if each matcher can be converted to Matcher<T>.
// This allows HasSubsequence() to accept polymorphic matchers like Not().
template <typename... M> class PolySubsequenceMatcher {
  std::tuple<M...> Matchers;

public:
  PolySubsequenceMatcher(M &&... Args)
      : Matchers(std::make_tuple(std::forward<M>(Args)...)) {}

  template <typename T> operator Matcher<const std::vector<T> &>() const {
    return ::testing::MakeMatcher(new SubsequenceMatcher<T>(
        TypedMatchers<T>(llvm::index_sequence_for<M...>{})));
  }

private:
  template <typename T, size_t... I>
  std::vector<Matcher<T>> TypedMatchers(llvm::index_sequence<I...>) const {
    return {std::get<I>(Matchers)...};
  }
};

// HasSubsequence(m1, m2, ...) matches a vector containing elements that match
// m1, m2 ... in that order.
// The real implementation is in SubsequenceMatcher.
template <typename... Args>
PolySubsequenceMatcher<Args...> HasSubsequence(Args &&... M) {
  return PolySubsequenceMatcher<Args...>(std::forward<Args>(M)...);
}

// EXPECT_ERROR seems like a pretty generic name, make sure it's not defined
// already.
#ifdef EXPECT_ERROR
#error "Refusing to redefine EXPECT_ERROR"
#endif

// Consumes llvm::Expected<T>, checks it contains an error and marks it as
// handled.
#define EXPECT_ERROR(expectedValue)                                            \
  do {                                                                         \
    auto &&ComputedValue = (expectedValue);                                    \
    if (ComputedValue) {                                                       \
      ADD_FAILURE() << "expected an error from " << #expectedValue             \
                    << " but got "                                             \
                    << ::testing::PrintToString(*ComputedValue);               \
      break;                                                                   \
    }                                                                          \
    llvm::consumeError(ComputedValue.takeError());                             \
  } while (false)

// Implements the HasValue(m) matcher for matching an Optional whose
// value matches matcher m.
template <typename InnerMatcher> class OptionalMatcher {
public:
  explicit OptionalMatcher(const InnerMatcher &matcher) : matcher_(matcher) {}

  // This type conversion operator template allows Optional(m) to be
  // used as a matcher for any Optional type whose value type is
  // compatible with the inner matcher.
  //
  // The reason we do this instead of relying on
  // MakePolymorphicMatcher() is that the latter is not flexible
  // enough for implementing the DescribeTo() method of Optional().
  template <typename Optional> operator Matcher<Optional>() const {
    return MakeMatcher(new Impl<Optional>(matcher_));
  }

private:
  // The monomorphic implementation that works for a particular optional type.
  template <typename Optional>
  class Impl : public ::testing::MatcherInterface<Optional> {
  public:
    using Value = typename std::remove_const<
        typename std::remove_reference<Optional>::type>::type::value_type;

    explicit Impl(const InnerMatcher &matcher)
        : matcher_(::testing::MatcherCast<const Value &>(matcher)) {}

    virtual void DescribeTo(::std::ostream *os) const {
      *os << "has a value that ";
      matcher_.DescribeTo(os);
    }

    virtual void DescribeNegationTo(::std::ostream *os) const {
      *os << "does not have a value that ";
      matcher_.DescribeTo(os);
    }

    virtual bool
    MatchAndExplain(Optional optional,
                    ::testing::MatchResultListener *listener) const {
      if (!optional.hasValue())
        return false;

      *listener << "which has a value ";
      return MatchPrintAndExplain(*optional, matcher_, listener);
    }

  private:
    const Matcher<const Value &> matcher_;

    GTEST_DISALLOW_ASSIGN_(Impl);
  };

  const InnerMatcher matcher_;

  GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
};

// Creates a matcher that matches an Optional that has a value
// that matches inner_matcher.
template <typename InnerMatcher>
inline OptionalMatcher<InnerMatcher>
HasValue(const InnerMatcher &inner_matcher) {
  return OptionalMatcher<InnerMatcher>(inner_matcher);
}

} // namespace clangd
} // namespace clang
#endif
