//===- unittest/Tooling/ExecutionTest.cpp - Tool execution tests. --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#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) {}
  FrontendAction *create() override { return new 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; }

  bool isSingleProcess() const override { return true; }

  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 llvm::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"},
                                                 std::vector<std::string>());
  AllTUsToolExecutor Executor(Compilations, /*ThreadCount=*/0);
  Executor.mapVirtualFile("a.cc", "void x() {}");
  Executor.mapVirtualFile("b.cc", "void y() {}");
  Executor.mapVirtualFile("c.cc", "void z() {}");

  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")));
}

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
