#include "TestingSupport.h"
#include "NoopAnalysis.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Testing/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

using namespace clang;
using namespace dataflow;

namespace {

using ::clang::ast_matchers::functionDecl;
using ::clang::ast_matchers::hasName;
using ::clang::ast_matchers::isDefinition;
using ::testing::_;
using ::testing::IsEmpty;
using ::testing::Pair;
using ::testing::UnorderedElementsAre;

template <typename T>
const FunctionDecl *findTargetFunc(ASTContext &Context, T FunctionMatcher) {
  auto TargetMatcher =
      functionDecl(FunctionMatcher, isDefinition()).bind("target");
  for (const auto &Node : ast_matchers::match(TargetMatcher, Context)) {
    const auto *Func = Node.template getNodeAs<FunctionDecl>("target");
    if (Func == nullptr)
      continue;
    if (Func->isTemplated())
      continue;
    return Func;
  }
  return nullptr;
}

void runTest(
    llvm::StringRef Code, llvm::StringRef TargetName,
    std::function<void(const llvm::DenseMap<const Stmt *, std::string> &)>
        RunChecks) {
  llvm::Annotations AnnotatedCode(Code);
  auto Unit = tooling::buildASTFromCodeWithArgs(
      AnnotatedCode.code(), {"-fsyntax-only", "-std=c++17"});
  auto &Context = Unit->getASTContext();
  const FunctionDecl *Func = findTargetFunc(Context, hasName(TargetName));
  ASSERT_NE(Func, nullptr);

  llvm::Expected<llvm::DenseMap<const Stmt *, std::string>> Mapping =
      test::buildStatementToAnnotationMapping(Func, AnnotatedCode);
  ASSERT_TRUE(static_cast<bool>(Mapping));

  RunChecks(Mapping.get());
}

TEST(BuildStatementToAnnotationMappingTest, ReturnStmt) {
  runTest(R"(
    int target() {
      return 42;
      /*[[ok]]*/
    }
  )",
          "target",
          [](const llvm::DenseMap<const Stmt *, std::string> &Annotations) {
            ASSERT_EQ(Annotations.size(), static_cast<unsigned int>(1));
            EXPECT_TRUE(isa<ReturnStmt>(Annotations.begin()->first));
            EXPECT_EQ(Annotations.begin()->second, "ok");
          });
}

void checkDataflow(
    llvm::StringRef Code, llvm::StringRef Target,
    std::function<void(llvm::ArrayRef<std::pair<
                           std::string, DataflowAnalysisState<NoopLattice>>>,
                       ASTContext &)>
        Expectations) {
  ASSERT_THAT_ERROR(
      test::checkDataflow<NoopAnalysis>(
          Code, Target,
          [](ASTContext &Context, Environment &) {
            return NoopAnalysis(Context, /*ApplyBuiltinTransfer=*/false);
          },
          std::move(Expectations), {"-fsyntax-only", "-std=c++17"}),
      llvm::Succeeded());
}

TEST(ProgramPointAnnotations, NoAnnotations) {
  ::testing::MockFunction<void(
      llvm::ArrayRef<
          std::pair<std::string, DataflowAnalysisState<NoopLattice>>>,
      ASTContext &)>
      Expectations;

  EXPECT_CALL(Expectations, Call(IsEmpty(), _)).Times(1);

  checkDataflow("void target() {}", "target", Expectations.AsStdFunction());
}

TEST(ProgramPointAnnotations, NoAnnotationsDifferentTarget) {
  ::testing::MockFunction<void(
      llvm::ArrayRef<
          std::pair<std::string, DataflowAnalysisState<NoopLattice>>>,
      ASTContext &)>
      Expectations;

  EXPECT_CALL(Expectations, Call(IsEmpty(), _)).Times(1);

  checkDataflow("void fun() {}", "fun", Expectations.AsStdFunction());
}

TEST(ProgramPointAnnotations, WithCodepoint) {
  ::testing::MockFunction<void(
      llvm::ArrayRef<
          std::pair<std::string, DataflowAnalysisState<NoopLattice>>>,
      ASTContext &)>
      Expectations;

  EXPECT_CALL(Expectations,
              Call(UnorderedElementsAre(Pair("program-point", _)), _))
      .Times(1);

  checkDataflow(R"cc(void target() {
                     int n;
                     // [[program-point]]
                   })cc",
                "target", Expectations.AsStdFunction());
}

TEST(ProgramPointAnnotations, MultipleCodepoints) {
  ::testing::MockFunction<void(
      llvm::ArrayRef<
          std::pair<std::string, DataflowAnalysisState<NoopLattice>>>,
      ASTContext &)>
      Expectations;

  EXPECT_CALL(Expectations,
              Call(UnorderedElementsAre(Pair("program-point-1", _),
                                        Pair("program-point-2", _)),
                   _))
      .Times(1);

  checkDataflow(R"cc(void target(bool b) {
                     if (b) {
                       int n;
                       // [[program-point-1]]
                     } else {
                       int m;
                       // [[program-point-2]]
                     }
                   })cc",
                "target", Expectations.AsStdFunction());
}

} // namespace
