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

#include "clang/CrossTU/CrossTranslationUnit.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ToolOutputFile.h"
#include "gtest/gtest.h"
#include <cassert>

namespace clang {
namespace cross_tu {

namespace {

class CTUASTConsumer : public clang::ASTConsumer {
public:
  explicit CTUASTConsumer(clang::CompilerInstance &CI, bool *Success)
      : CTU(CI), Success(Success) {}

  void HandleTranslationUnit(ASTContext &Ctx) {
    const TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
    const FunctionDecl *FD = nullptr;
    for (const Decl *D : TU->decls()) {
      FD = dyn_cast<FunctionDecl>(D);
      if (FD && FD->getName() == "f")
        break;
    }
    assert(FD && FD->getName() == "f");
    bool OrigFDHasBody = FD->hasBody();

    // Prepare the index file and the AST file.
    int ASTFD;
    llvm::SmallString<256> ASTFileName;
    ASSERT_FALSE(
        llvm::sys::fs::createTemporaryFile("f_ast", "ast", ASTFD, ASTFileName));
    llvm::ToolOutputFile ASTFile(ASTFileName, ASTFD);

    int IndexFD;
    llvm::SmallString<256> IndexFileName;
    ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("index", "txt", IndexFD,
                                                    IndexFileName));
    llvm::ToolOutputFile IndexFile(IndexFileName, IndexFD);
    IndexFile.os() << "c:@F@f#I# " << ASTFileName << "\n";
    IndexFile.os().flush();
    EXPECT_TRUE(llvm::sys::fs::exists(IndexFileName));

    StringRef SourceText = "int f(int) { return 0; }\n";
    // This file must exist since the saved ASTFile will reference it.
    int SourceFD;
    llvm::SmallString<256> SourceFileName;
    ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("input", "cpp", SourceFD,
                                                    SourceFileName));
    llvm::ToolOutputFile SourceFile(SourceFileName, SourceFD);
    SourceFile.os() << SourceText;
    SourceFile.os().flush();
    EXPECT_TRUE(llvm::sys::fs::exists(SourceFileName));

    std::unique_ptr<ASTUnit> ASTWithDefinition =
        tooling::buildASTFromCode(SourceText, SourceFileName);
    ASTWithDefinition->Save(ASTFileName.str());
    EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName));

    // Load the definition from the AST file.
    llvm::Expected<const FunctionDecl *> NewFDorError =
        CTU.getCrossTUDefinition(FD, "", IndexFileName);
    EXPECT_TRUE((bool)NewFDorError);
    const FunctionDecl *NewFD = *NewFDorError;

    *Success = NewFD && NewFD->hasBody() && !OrigFDHasBody;
  }

private:
  CrossTranslationUnitContext CTU;
  bool *Success;
};

class CTUAction : public clang::ASTFrontendAction {
public:
  CTUAction(bool *Success) : Success(Success) {}

protected:
  std::unique_ptr<clang::ASTConsumer>
  CreateASTConsumer(clang::CompilerInstance &CI, StringRef) override {
    return llvm::make_unique<CTUASTConsumer>(CI, Success);
  }

private:
  bool *Success;
};

} // end namespace

TEST(CrossTranslationUnit, CanLoadFunctionDefinition) {
  bool Success = false;
  EXPECT_TRUE(tooling::runToolOnCode(new CTUAction(&Success), "int f(int);"));
  EXPECT_TRUE(Success);
}

TEST(CrossTranslationUnit, IndexFormatCanBeParsed) {
  llvm::StringMap<std::string> Index;
  Index["a"] = "/b/f1";
  Index["c"] = "/d/f2";
  Index["e"] = "/f/f3";
  std::string IndexText = createCrossTUIndexString(Index);

  int IndexFD;
  llvm::SmallString<256> IndexFileName;
  ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("index", "txt", IndexFD,
                                                  IndexFileName));
  llvm::ToolOutputFile IndexFile(IndexFileName, IndexFD);
  IndexFile.os() << IndexText;
  IndexFile.os().flush();
  EXPECT_TRUE(llvm::sys::fs::exists(IndexFileName));
  llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
      parseCrossTUIndex(IndexFileName, "");
  EXPECT_TRUE((bool)IndexOrErr);
  llvm::StringMap<std::string> ParsedIndex = IndexOrErr.get();
  for (const auto &E : Index) {
    EXPECT_TRUE(ParsedIndex.count(E.getKey()));
    EXPECT_EQ(ParsedIndex[E.getKey()], E.getValue());
  }
  for (const auto &E : ParsedIndex)
    EXPECT_TRUE(Index.count(E.getKey()));
}

TEST(CrossTranslationUnit, CTUDirIsHandledCorrectly) {
  llvm::StringMap<std::string> Index;
  Index["a"] = "/b/c/d";
  std::string IndexText = createCrossTUIndexString(Index);

  int IndexFD;
  llvm::SmallString<256> IndexFileName;
  ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("index", "txt", IndexFD,
                                                  IndexFileName));
  llvm::ToolOutputFile IndexFile(IndexFileName, IndexFD);
  IndexFile.os() << IndexText;
  IndexFile.os().flush();
  EXPECT_TRUE(llvm::sys::fs::exists(IndexFileName));
  llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
      parseCrossTUIndex(IndexFileName, "/ctudir");
  EXPECT_TRUE((bool)IndexOrErr);
  llvm::StringMap<std::string> ParsedIndex = IndexOrErr.get();
  EXPECT_EQ(ParsedIndex["a"], "/ctudir/b/c/d");
}

} // end namespace cross_tu
} // end namespace clang
