//===-- IncludeFixerContext.cpp - Include fixer context ---------*- C++ -*-===//
//
// 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 "IncludeFixerContext.h"
#include "llvm/ADT/STLExtras.h"

namespace clang {
namespace include_fixer {

namespace {

// Splits a multiply qualified names (e.g. a::b::c).
llvm::SmallVector<llvm::StringRef, 8>
SplitQualifiers(llvm::StringRef StringQualifiers) {
  llvm::SmallVector<llvm::StringRef, 8> Qualifiers;
  StringQualifiers.split(Qualifiers, "::");
  return Qualifiers;
}

std::string createQualifiedNameForReplacement(
    llvm::StringRef RawSymbolName,
    llvm::StringRef SymbolScopedQualifiersName,
    const find_all_symbols::SymbolInfo &MatchedSymbol) {
  // No need to add missing qualifiers if SymbolIdentifier has a global scope
  // operator "::".
  if (RawSymbolName.starts_with("::"))
    return std::string(RawSymbolName);

  std::string QualifiedName = MatchedSymbol.getQualifiedName();

  // For nested classes, the qualified name constructed from database misses
  // some stripped qualifiers, because when we search a symbol in database,
  // we strip qualifiers from the end until we find a result. So append the
  // missing stripped qualifiers here.
  //
  // Get stripped qualifiers.
  auto SymbolQualifiers = SplitQualifiers(RawSymbolName);
  std::string StrippedQualifiers;
  while (!SymbolQualifiers.empty() &&
         !llvm::StringRef(QualifiedName).ends_with(SymbolQualifiers.back())) {
    StrippedQualifiers =
        "::" + SymbolQualifiers.back().str() + StrippedQualifiers;
    SymbolQualifiers.pop_back();
  }
  // Append the missing stripped qualifiers.
  std::string FullyQualifiedName = QualifiedName + StrippedQualifiers;

  // Try to find and skip the common prefix qualifiers.
  auto FullySymbolQualifiers = SplitQualifiers(FullyQualifiedName);
  auto ScopedQualifiers = SplitQualifiers(SymbolScopedQualifiersName);
  auto FullySymbolQualifiersIter = FullySymbolQualifiers.begin();
  auto SymbolScopedQualifiersIter = ScopedQualifiers.begin();
  while (FullySymbolQualifiersIter != FullySymbolQualifiers.end() &&
         SymbolScopedQualifiersIter != ScopedQualifiers.end()) {
    if (*FullySymbolQualifiersIter != *SymbolScopedQualifiersIter)
      break;
    ++FullySymbolQualifiersIter;
    ++SymbolScopedQualifiersIter;
  }
  std::string Result;
  for (; FullySymbolQualifiersIter != FullySymbolQualifiers.end();
       ++FullySymbolQualifiersIter) {
    if (!Result.empty())
      Result += "::";
    Result += *FullySymbolQualifiersIter;
  }
  return Result;
}

} // anonymous namespace

IncludeFixerContext::IncludeFixerContext(
    StringRef FilePath, std::vector<QuerySymbolInfo> QuerySymbols,
    std::vector<find_all_symbols::SymbolInfo> Symbols)
    : FilePath(FilePath), QuerySymbolInfos(std::move(QuerySymbols)),
      MatchedSymbols(std::move(Symbols)) {
  // Remove replicated QuerySymbolInfos with the same range.
  //
  // QuerySymbolInfos may contain replicated elements. Because CorrectTypo
  // callback doesn't always work as we expected. In somecases, it will be
  // triggered at the same position or unidentified symbol multiple times.
  llvm::sort(QuerySymbolInfos,
             [&](const QuerySymbolInfo &A, const QuerySymbolInfo &B) {
               return std::make_pair(A.Range.getOffset(), A.Range.getLength()) <
                      std::make_pair(B.Range.getOffset(), B.Range.getLength());
             });
  QuerySymbolInfos.erase(
      std::unique(QuerySymbolInfos.begin(), QuerySymbolInfos.end(),
                  [](const QuerySymbolInfo &A, const QuerySymbolInfo &B) {
                    return A.Range == B.Range;
                  }),
      QuerySymbolInfos.end());
  for (const auto &Symbol : MatchedSymbols) {
    HeaderInfos.push_back(
        {Symbol.getFilePath().str(),
         createQualifiedNameForReplacement(
             QuerySymbolInfos.front().RawIdentifier,
             QuerySymbolInfos.front().ScopedQualifiers, Symbol)});
  }
  // Deduplicate header infos.
  HeaderInfos.erase(std::unique(HeaderInfos.begin(), HeaderInfos.end(),
                                [](const HeaderInfo &A, const HeaderInfo &B) {
                                  return A.Header == B.Header &&
                                         A.QualifiedName == B.QualifiedName;
                                }),
                    HeaderInfos.end());
}

} // include_fixer
} // clang
