//===- unittest/Tooling/ExecutionTest.cpp - Tool execution tests. --------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "clang/Tooling/Execution.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/AllTUsExecution.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/StandaloneExecution.h"
#include "clang/Tooling/ToolExecutorPluginRegistry.h"
#include "clang/Tooling/Tooling.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <algorithm>
#include <string>

namespace clang {
namespace tooling {

namespace {

// This traverses the AST and outputs function name as key and "1" as value for
// each function declaration.
class ASTConsumerWithResult
    : public ASTConsumer,
      public RecursiveASTVisitor<ASTConsumerWithResult> {
public:
  using ASTVisitor = RecursiveASTVisitor<ASTConsumerWithResult>;

  explicit ASTConsumerWithResult(ExecutionContext *Context) : Context(Context) {
    assert(Context != nullptr);
  }

  void HandleTranslationUnit(clang::ASTContext &Context) override {
    TraverseDecl(Context.getTranslationUnitDecl());
  }

  bool TraverseFunctionDecl(clang::FunctionDecl *Decl) {
    Context->reportResult(Decl->getNameAsString(),
                          Context->getRevision() + ":" + Context->getCorpus() +
                              ":" + Context->getCurrentCompilationUnit() +
                              "/1");
    return ASTVisitor::TraverseFunctionDecl(Decl);
  }

private:
  ExecutionContext *const Context;
};

class ReportResultAction : public ASTFrontendAction {
public:
  explicit ReportResultAction(ExecutionContext *Context) : Context(Context) {
    assert(Context != nullptr);
  }

protected:
  std::unique_ptr<clang::ASTConsumer>
  CreateASTConsumer(clang::CompilerInstance &compiler,
                    StringRef /* dummy */) override {
    std::unique_ptr<clang::ASTConsumer> ast_consumer{
        new ASTConsumerWithResult(Context)};
    return ast_consumer;
  }

private:
  ExecutionContext *const Context;
};

class ReportResultActionFactory : public FrontendActionFactory {
public:
  ReportResultActionFactory(ExecutionContext *Context) : Context(Context) {}
  std::unique_ptr<FrontendAction> create() override {
    return std::make_unique<ReportResultAction>(Context);
  }

private:
  ExecutionContext *const Context;
};

} // namespace

class TestToolExecutor : public ToolExecutor {
public:
  static const char *ExecutorName;

  TestToolExecutor(CommonOptionsParser Options)
      : OptionsParser(std::move(Options)) {}

  StringRef getExecutorName() const override { return ExecutorName; }

  llvm::Error
  execute(llvm::ArrayRef<std::pair<std::unique_ptr<FrontendActionFactory>,
                                   ArgumentsAdjuster>>) override {
    return llvm::Error::success();
  }

  ExecutionContext *getExecutionContext() override { return nullptr; };

  ToolResults *getToolResults() override { return nullptr; }

  llvm::ArrayRef<std::string> getSourcePaths() const {
    return OptionsParser.getSourcePathList();
  }

  void mapVirtualFile(StringRef FilePath, StringRef Content) override {
    VFS[FilePath] = Content;
  }

private:
  CommonOptionsParser OptionsParser;
  std::string SourcePaths;
  std::map<std::string, std::string> VFS;
};

const char *TestToolExecutor::ExecutorName = "test-executor";

class TestToolExecutorPlugin : public ToolExecutorPlugin {
public:
  llvm::Expected<std::unique_ptr<ToolExecutor>>
  create(CommonOptionsParser &OptionsParser) override {
    return std::make_unique<TestToolExecutor>(std::move(OptionsParser));
  }
};

static ToolExecutorPluginRegistry::Add<TestToolExecutorPlugin>
    X("test-executor", "Plugin for TestToolExecutor.");

llvm::cl::OptionCategory TestCategory("execution-test options");

TEST(CreateToolExecutorTest, FailedCreateExecutorUndefinedFlag) {
  std::vector<const char *> argv = {"prog", "--fake_flag_no_no_no", "f"};
  int argc = argv.size();
  auto Executor = internal::createExecutorFromCommandLineArgsImpl(
      argc, &argv[0], TestCategory);
  ASSERT_FALSE((bool)Executor);
  llvm::consumeError(Executor.takeError());
}

TEST(CreateToolExecutorTest, RegisterFlagsBeforeReset) {
  llvm::cl::opt<std::string> BeforeReset(
      "before_reset", llvm::cl::desc("Defined before reset."),
      llvm::cl::init(""));

  llvm::cl::ResetAllOptionOccurrences();

  std::vector<const char *> argv = {"prog", "--before_reset=set", "f"};
  int argc = argv.size();
  auto Executor = internal::createExecutorFromCommandLineArgsImpl(
      argc, &argv[0], TestCategory);
  ASSERT_TRUE((bool)Executor);
  EXPECT_EQ(BeforeReset, "set");
  BeforeReset.removeArgument();
}

TEST(CreateToolExecutorTest, CreateStandaloneToolExecutor) {
  std::vector<const char *> argv = {"prog", "standalone.cpp"};
  int argc = argv.size();
  auto Executor = internal::createExecutorFromCommandLineArgsImpl(
      argc, &argv[0], TestCategory);
  ASSERT_TRUE((bool)Executor);
  EXPECT_EQ(Executor->get()->getExecutorName(),
            StandaloneToolExecutor::ExecutorName);
}

TEST(CreateToolExecutorTest, CreateTestToolExecutor) {
  std::vector<const char *> argv = {"prog", "test.cpp",
                                    "--executor=test-executor"};
  int argc = argv.size();
  auto Executor = internal::createExecutorFromCommandLineArgsImpl(
      argc, &argv[0], TestCategory);
  ASSERT_TRUE((bool)Executor);
  EXPECT_EQ(Executor->get()->getExecutorName(), TestToolExecutor::ExecutorName);
}

TEST(StandaloneToolTest, SynctaxOnlyActionOnSimpleCode) {
  FixedCompilationDatabase Compilations(".", std::vector<std::string>());
  StandaloneToolExecutor Executor(Compilations,
                                  std::vector<std::string>(1, "a.cc"));
  Executor.mapVirtualFile("a.cc", "int x = 0;");

  auto Err = Executor.execute(newFrontendActionFactory<SyntaxOnlyAction>(),
                              getClangSyntaxOnlyAdjuster());
  ASSERT_TRUE(!Err);
}

TEST(StandaloneToolTest, SimpleAction) {
  FixedCompilationDatabase Compilations(".", std::vector<std::string>());
  StandaloneToolExecutor Executor(Compilations,
                                  std::vector<std::string>(1, "a.cc"));
  Executor.mapVirtualFile("a.cc", "int x = 0;");

  auto Err = Executor.execute(std::unique_ptr<FrontendActionFactory>(
      new ReportResultActionFactory(Executor.getExecutionContext())));
  ASSERT_TRUE(!Err);
  auto KVs = Executor.getToolResults()->AllKVResults();
  ASSERT_EQ(KVs.size(), 0u);
}

TEST(StandaloneToolTest, SimpleActionWithResult) {
  FixedCompilationDatabase Compilations(".", std::vector<std::string>());
  StandaloneToolExecutor Executor(Compilations,
                                  std::vector<std::string>(1, "a.cc"));
  Executor.mapVirtualFile("a.cc", "int x = 0; void f() {}");

  auto Err = Executor.execute(std::unique_ptr<FrontendActionFactory>(
      new ReportResultActionFactory(Executor.getExecutionContext())));
  ASSERT_TRUE(!Err);
  auto KVs = Executor.getToolResults()->AllKVResults();
  ASSERT_EQ(KVs.size(), 1u);
  EXPECT_EQ("f", KVs[0].first);
  // Currently the standlone executor returns empty corpus, revision, and
  // compilation unit.
  EXPECT_EQ("::/1", KVs[0].second);

  Executor.getToolResults()->forEachResult(
      [](StringRef, StringRef Value) { EXPECT_EQ("::/1", Value); });
}

class FixedCompilationDatabaseWithFiles : public CompilationDatabase {
public:
  FixedCompilationDatabaseWithFiles(Twine Directory,
                                    ArrayRef<std::string> Files,
                                    ArrayRef<std::string> CommandLine)
      : FixedCompilations(Directory, CommandLine), Files(Files) {}

  std::vector<CompileCommand>
  getCompileCommands(StringRef FilePath) const override {
    return FixedCompilations.getCompileCommands(FilePath);
  }

  std::vector<std::string> getAllFiles() const override { return Files; }

private:
  FixedCompilationDatabase FixedCompilations;
  std::vector<std::string> Files;
};

MATCHER_P(Named, Name, "") { return arg.first == Name; }

TEST(AllTUsToolTest, AFewFiles) {
  FixedCompilationDatabaseWithFiles Compilations(
      ".", {"a.cc", "b.cc", "c.cc", "ignore.cc"}, std::vector<std::string>());
  AllTUsToolExecutor Executor(Compilations, /*ThreadCount=*/0);
  Filter.setValue("[a-c].cc");
  Executor.mapVirtualFile("a.cc", "void x() {}");
  Executor.mapVirtualFile("b.cc", "void y() {}");
  Executor.mapVirtualFile("c.cc", "void z() {}");
  Executor.mapVirtualFile("ignore.cc", "void d() {}");

  auto Err = Executor.execute(std::unique_ptr<FrontendActionFactory>(
      new ReportResultActionFactory(Executor.getExecutionContext())));
  ASSERT_TRUE(!Err);
  EXPECT_THAT(
      Executor.getToolResults()->AllKVResults(),
      ::testing::UnorderedElementsAre(Named("x"), Named("y"), Named("z")));
  Filter.setValue(".*"); // reset to default value.
}

TEST(AllTUsToolTest, ManyFiles) {
  unsigned NumFiles = 100;
  std::vector<std::string> Files;
  std::map<std::string, std::string> FileToContent;
  std::vector<std::string> ExpectedSymbols;
  for (unsigned i = 1; i <= NumFiles; ++i) {
    std::string File = "f" + std::to_string(i) + ".cc";
    std::string Symbol = "looong_function_name_" + std::to_string(i);
    Files.push_back(File);
    FileToContent[File] = "void " + Symbol + "() {}";
    ExpectedSymbols.push_back(Symbol);
  }
  FixedCompilationDatabaseWithFiles Compilations(".", Files,
                                                 std::vector<std::string>());
  AllTUsToolExecutor Executor(Compilations, /*ThreadCount=*/0);
  for (const auto &FileAndContent : FileToContent) {
    Executor.mapVirtualFile(FileAndContent.first, FileAndContent.second);
  }

  auto Err = Executor.execute(std::unique_ptr<FrontendActionFactory>(
      new ReportResultActionFactory(Executor.getExecutionContext())));
  ASSERT_TRUE(!Err);
  std::vector<std::string> Results;
  Executor.getToolResults()->forEachResult(
      [&](StringRef Name, StringRef) { Results.push_back(Name); });
  EXPECT_THAT(ExpectedSymbols, ::testing::UnorderedElementsAreArray(Results));
}

} // end namespace tooling
} // end namespace clang
