//===--- FindSymbols.cpp ------------------------------------*- C++-*------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "FindSymbols.h"

#include "AST.h"
#include "ClangdUnit.h"
#include "FuzzyMatch.h"
#include "Logger.h"
#include "Quality.h"
#include "SourceCode.h"
#include "index/Index.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/Index/IndexSymbol.h"
#include "clang/Index/IndexingAction.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Path.h"

#define DEBUG_TYPE "FindSymbols"

namespace clang {
namespace clangd {

namespace {

// Convert a index::SymbolKind to clangd::SymbolKind (LSP)
// Note, some are not perfect matches and should be improved when this LSP
// issue is addressed:
// https://github.com/Microsoft/language-server-protocol/issues/344
SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind) {
  switch (Kind) {
  case index::SymbolKind::Unknown:
    return SymbolKind::Variable;
  case index::SymbolKind::Module:
    return SymbolKind::Module;
  case index::SymbolKind::Namespace:
    return SymbolKind::Namespace;
  case index::SymbolKind::NamespaceAlias:
    return SymbolKind::Namespace;
  case index::SymbolKind::Macro:
    return SymbolKind::String;
  case index::SymbolKind::Enum:
    return SymbolKind::Enum;
  case index::SymbolKind::Struct:
    return SymbolKind::Struct;
  case index::SymbolKind::Class:
    return SymbolKind::Class;
  case index::SymbolKind::Protocol:
    return SymbolKind::Interface;
  case index::SymbolKind::Extension:
    return SymbolKind::Interface;
  case index::SymbolKind::Union:
    return SymbolKind::Class;
  case index::SymbolKind::TypeAlias:
    return SymbolKind::Class;
  case index::SymbolKind::Function:
    return SymbolKind::Function;
  case index::SymbolKind::Variable:
    return SymbolKind::Variable;
  case index::SymbolKind::Field:
    return SymbolKind::Field;
  case index::SymbolKind::EnumConstant:
    return SymbolKind::EnumMember;
  case index::SymbolKind::InstanceMethod:
  case index::SymbolKind::ClassMethod:
  case index::SymbolKind::StaticMethod:
    return SymbolKind::Method;
  case index::SymbolKind::InstanceProperty:
  case index::SymbolKind::ClassProperty:
  case index::SymbolKind::StaticProperty:
    return SymbolKind::Property;
  case index::SymbolKind::Constructor:
  case index::SymbolKind::Destructor:
    return SymbolKind::Method;
  case index::SymbolKind::ConversionFunction:
    return SymbolKind::Function;
  case index::SymbolKind::Parameter:
    return SymbolKind::Variable;
  case index::SymbolKind::Using:
    return SymbolKind::Namespace;
  }
  llvm_unreachable("invalid symbol kind");
}

using ScoredSymbolInfo = std::pair<float, SymbolInformation>;
struct ScoredSymbolGreater {
  bool operator()(const ScoredSymbolInfo &L, const ScoredSymbolInfo &R) {
    if (L.first != R.first)
      return L.first > R.first;
    return L.second.name < R.second.name; // Earlier name is better.
  }
};

} // namespace

llvm::Expected<std::vector<SymbolInformation>>
getWorkspaceSymbols(StringRef Query, int Limit, const SymbolIndex *const Index,
                    StringRef HintPath) {
  std::vector<SymbolInformation> Result;
  if (Query.empty() || !Index)
    return Result;

  auto Names = splitQualifiedName(Query);

  FuzzyFindRequest Req;
  Req.Query = Names.second;

  // FuzzyFind doesn't want leading :: qualifier
  bool IsGlobalQuery = Names.first.consume_front("::");
  // Restrict results to the scope in the query string if present (global or
  // not).
  if (IsGlobalQuery || !Names.first.empty())
    Req.Scopes = {Names.first};
  if (Limit)
    Req.MaxCandidateCount = Limit;
  TopN<ScoredSymbolInfo, ScoredSymbolGreater> Top(Req.MaxCandidateCount);
  FuzzyMatcher Filter(Req.Query);
  Index->fuzzyFind(Req, [HintPath, &Top, &Filter](const Symbol &Sym) {
    // Prefer the definition over e.g. a function declaration in a header
    auto &CD = Sym.Definition ? Sym.Definition : Sym.CanonicalDeclaration;
    auto Uri = URI::parse(CD.FileURI);
    if (!Uri) {
      log("Workspace symbol: Could not parse URI '{0}' for symbol '{1}'.",
          CD.FileURI, Sym.Name);
      return;
    }
    auto Path = URI::resolve(*Uri, HintPath);
    if (!Path) {
      log("Workspace symbol: Could not resolve path for URI '{0}' for symbol "
          "'{1}'.",
          Uri->toString(), Sym.Name);
      return;
    }
    Location L;
    L.uri = URIForFile((*Path));
    Position Start, End;
    Start.line = CD.Start.Line;
    Start.character = CD.Start.Column;
    End.line = CD.End.Line;
    End.character = CD.End.Column;
    L.range = {Start, End};
    SymbolKind SK = indexSymbolKindToSymbolKind(Sym.SymInfo.Kind);
    std::string Scope = Sym.Scope;
    StringRef ScopeRef = Scope;
    ScopeRef.consume_back("::");
    SymbolInformation Info = {Sym.Name, SK, L, ScopeRef};

    SymbolQualitySignals Quality;
    Quality.merge(Sym);
    SymbolRelevanceSignals Relevance;
    Relevance.Query = SymbolRelevanceSignals::Generic;
    if (auto NameMatch = Filter.match(Sym.Name))
      Relevance.NameMatch = *NameMatch;
    else {
      log("Workspace symbol: {0} didn't match query {1}", Sym.Name,
          Filter.pattern());
      return;
    }
    Relevance.merge(Sym);
    auto Score =
        evaluateSymbolAndRelevance(Quality.evaluate(), Relevance.evaluate());
    dlog("FindSymbols: {0}{1} = {2}\n{3}{4}\n", Sym.Scope, Sym.Name, Score,
         Quality, Relevance);

    Top.push({Score, std::move(Info)});
  });
  for (auto &R : std::move(Top).items())
    Result.push_back(std::move(R.second));
  return Result;
}

namespace {
/// Finds document symbols in the main file of the AST.
class DocumentSymbolsConsumer : public index::IndexDataConsumer {
  ASTContext &AST;
  std::vector<SymbolInformation> Symbols;
  // We are always list document for the same file, so cache the value.
  llvm::Optional<URIForFile> MainFileUri;

public:
  DocumentSymbolsConsumer(ASTContext &AST) : AST(AST) {}
  std::vector<SymbolInformation> takeSymbols() { return std::move(Symbols); }

  void initialize(ASTContext &Ctx) override {
    // Compute the absolute path of the main file which we will use for all
    // results.
    const SourceManager &SM = AST.getSourceManager();
    const FileEntry *F = SM.getFileEntryForID(SM.getMainFileID());
    if (!F)
      return;
    auto FilePath = getAbsoluteFilePath(F, SM);
    if (FilePath)
      MainFileUri = URIForFile(*FilePath);
  }

  bool shouldIncludeSymbol(const NamedDecl *ND) {
    if (!ND || ND->isImplicit())
      return false;
    // Skip anonymous declarations, e.g (anonymous enum/class/struct).
    if (ND->getDeclName().isEmpty())
      return false;
    return true;
  }

  bool
  handleDeclOccurence(const Decl *, index::SymbolRoleSet Roles,
                      ArrayRef<index::SymbolRelation> Relations,
                      SourceLocation Loc,
                      index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
    assert(ASTNode.OrigD);
    // No point in continuing the index consumer if we could not get the
    // absolute path of the main file.
    if (!MainFileUri)
      return false;
    // We only want declarations and definitions, i.e. no references.
    if (!(Roles & static_cast<unsigned>(index::SymbolRole::Declaration) ||
          Roles & static_cast<unsigned>(index::SymbolRole::Definition)))
      return true;
    SourceLocation NameLoc = findNameLoc(ASTNode.OrigD);
    const SourceManager &SourceMgr = AST.getSourceManager();
    // We should be only be looking at "local" decls in the main file.
    if (!SourceMgr.isWrittenInMainFile(NameLoc)) {
      // Even thought we are visiting only local (non-preamble) decls,
      // we can get here when in the presense of "extern" decls.
      return true;
    }
    const NamedDecl *ND = llvm::dyn_cast<NamedDecl>(ASTNode.OrigD);
    if (!shouldIncludeSymbol(ND))
      return true;

    SourceLocation EndLoc =
        Lexer::getLocForEndOfToken(NameLoc, 0, SourceMgr, AST.getLangOpts());
    Position Begin = sourceLocToPosition(SourceMgr, NameLoc);
    Position End = sourceLocToPosition(SourceMgr, EndLoc);
    Range R = {Begin, End};
    Location L;
    L.uri = *MainFileUri;
    L.range = R;

    std::string QName = printQualifiedName(*ND);
    StringRef Scope, Name;
    std::tie(Scope, Name) = splitQualifiedName(QName);
    Scope.consume_back("::");

    index::SymbolInfo SymInfo = index::getSymbolInfo(ND);
    SymbolKind SK = indexSymbolKindToSymbolKind(SymInfo.Kind);

    SymbolInformation SI;
    SI.name = Name;
    SI.kind = SK;
    SI.location = L;
    SI.containerName = Scope;
    Symbols.push_back(std::move(SI));
    return true;
  }
};
} // namespace

llvm::Expected<std::vector<SymbolInformation>>
getDocumentSymbols(ParsedAST &AST) {
  DocumentSymbolsConsumer DocumentSymbolsCons(AST.getASTContext());

  index::IndexingOptions IndexOpts;
  IndexOpts.SystemSymbolFilter =
      index::IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly;
  IndexOpts.IndexFunctionLocals = false;
  indexTopLevelDecls(AST.getASTContext(), AST.getLocalTopLevelDecls(),
                     DocumentSymbolsCons, IndexOpts);

  return DocumentSymbolsCons.takeSymbols();
}

} // namespace clangd
} // namespace clang
