//===--- IndexTests.cpp - Test indexing actions -----------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/Index/IndexSymbol.h"
#include "clang/Index/IndexingAction.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/StringRef.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <memory>

namespace clang {
namespace index {

struct TestSymbol {
  std::string QName;
  // FIXME: add more information.
};

llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const TestSymbol &S) {
  return OS << S.QName;
}

namespace {
class Indexer : public IndexDataConsumer {
public:
  bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
                           ArrayRef<SymbolRelation>, SourceLocation,
                           ASTNodeInfo) override {
    const auto *ND = llvm::dyn_cast<NamedDecl>(D);
    if (!ND)
      return true;
    TestSymbol S;
    S.QName = ND->getQualifiedNameAsString();
    Symbols.push_back(std::move(S));
    return true;
  }

  bool handleMacroOccurence(const IdentifierInfo *Name, const MacroInfo *,
                            SymbolRoleSet, SourceLocation) override {
    TestSymbol S;
    S.QName = Name->getName();
    Symbols.push_back(std::move(S));
    return true;
  }

  std::vector<TestSymbol> Symbols;
};

class IndexAction : public ASTFrontendAction {
public:
  IndexAction(std::shared_ptr<Indexer> Index,
              IndexingOptions Opts = IndexingOptions())
      : Index(std::move(Index)), Opts(Opts) {}

protected:
  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                 StringRef InFile) override {
    class Consumer : public ASTConsumer {
      std::shared_ptr<Indexer> Index;
      std::shared_ptr<Preprocessor> PP;
      IndexingOptions Opts;

    public:
      Consumer(std::shared_ptr<Indexer> Index, std::shared_ptr<Preprocessor> PP,
               IndexingOptions Opts)
          : Index(std::move(Index)), PP(std::move(PP)), Opts(Opts) {}

      void HandleTranslationUnit(ASTContext &Ctx) override {
        std::vector<Decl *> DeclsToIndex(
            Ctx.getTranslationUnitDecl()->decls().begin(),
            Ctx.getTranslationUnitDecl()->decls().end());
        indexTopLevelDecls(Ctx, *PP, DeclsToIndex, *Index, Opts);
      }
    };
    return llvm::make_unique<Consumer>(Index, CI.getPreprocessorPtr(), Opts);
  }

private:
  std::shared_ptr<Indexer> Index;
  IndexingOptions Opts;
};

using testing::Contains;
using testing::Not;
using testing::UnorderedElementsAre;

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

TEST(IndexTest, Simple) {
  auto Index = std::make_shared<Indexer>();
  tooling::runToolOnCode(new IndexAction(Index), "class X {}; void f() {}");
  EXPECT_THAT(Index->Symbols, UnorderedElementsAre(QName("X"), QName("f")));
}

TEST(IndexTest, IndexPreprocessorMacros) {
  std::string Code = "#define INDEX_MAC 1";
  auto Index = std::make_shared<Indexer>();
  IndexingOptions Opts;
  Opts.IndexMacrosInPreprocessor = true;
  tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
  EXPECT_THAT(Index->Symbols, Contains(QName("INDEX_MAC")));

  Opts.IndexMacrosInPreprocessor = false;
  Index->Symbols.clear();
  tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
  EXPECT_THAT(Index->Symbols, UnorderedElementsAre());
}

} // namespace
} // namespace index
} // namespace clang
