//===--- CodeCompletionStrings.cpp -------------------------------*- 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 "CodeCompletionStrings.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/RawCommentList.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "llvm/Support/JSON.h"
#include <limits>
#include <utility>

namespace clang {
namespace clangd {
namespace {

bool isInformativeQualifierChunk(CodeCompletionString::Chunk const &Chunk) {
  return Chunk.Kind == CodeCompletionString::CK_Informative &&
         llvm::StringRef(Chunk.Text).endswith("::");
}

void appendEscapeSnippet(const llvm::StringRef Text, std::string *Out) {
  for (const auto Character : Text) {
    if (Character == '$' || Character == '}' || Character == '\\')
      Out->push_back('\\');
    Out->push_back(Character);
  }
}

void appendOptionalChunk(const CodeCompletionString &CCS, std::string *Out) {
  for (const CodeCompletionString::Chunk &C : CCS) {
    switch (C.Kind) {
    case CodeCompletionString::CK_Optional:
      assert(C.Optional &&
             "Expected the optional code completion string to be non-null.");
      appendOptionalChunk(*C.Optional, Out);
      break;
    default:
      *Out += C.Text;
      break;
    }
  }
}

bool looksLikeDocComment(llvm::StringRef CommentText) {
  // We don't report comments that only contain "special" chars.
  // This avoids reporting various delimiters, like:
  //   =================
  //   -----------------
  //   *****************
  return CommentText.find_first_not_of("/*-= \t\r\n") != llvm::StringRef::npos;
}

} // namespace

std::string getDocComment(const ASTContext &Ctx,
                          const CodeCompletionResult &Result,
                          bool CommentsFromHeaders) {
  // FIXME: clang's completion also returns documentation for RK_Pattern if they
  // contain a pattern for ObjC properties. Unfortunately, there is no API to
  // get this declaration, so we don't show documentation in that case.
  if (Result.Kind != CodeCompletionResult::RK_Declaration)
    return "";
  return Result.getDeclaration() ? getDeclComment(Ctx, *Result.getDeclaration())
                                 : "";
}

std::string getDeclComment(const ASTContext &Ctx, const NamedDecl &Decl) {
  if (isa<NamespaceDecl>(Decl)) {
    // Namespaces often have too many redecls for any particular redecl comment
    // to be useful. Moreover, we often confuse file headers or generated
    // comments with namespace comments. Therefore we choose to just ignore
    // the comments for namespaces.
    return "";
  }
  const RawComment *RC = getCompletionComment(Ctx, &Decl);
  if (!RC)
    return "";
  // Sanity check that the comment does not come from the PCH. We choose to not
  // write them into PCH, because they are racy and slow to load.
  assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc()));
  std::string Doc =
      RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics());
  if (!looksLikeDocComment(Doc))
    return "";
  // Clang requires source to be UTF-8, but doesn't enforce this in comments.
  if (!llvm::json::isUTF8(Doc))
    Doc = llvm::json::fixUTF8(Doc);
  return Doc;
}

void getSignature(const CodeCompletionString &CCS, std::string *Signature,
                  std::string *Snippet, std::string *RequiredQualifiers,
                  bool CompletingPattern) {
  // Placeholder with this index will be ${0:…} to mark final cursor position.
  // Usually we do not add $0, so the cursor is placed at end of completed text.
  unsigned CursorSnippetArg = std::numeric_limits<unsigned>::max();
  if (CompletingPattern) {
    // In patterns, it's best to place the cursor at the last placeholder, to
    // handle cases like
    //    namespace ${1:name} {
    //      ${0:decls}
    //    }
    CursorSnippetArg =
        llvm::count_if(CCS, [](const CodeCompletionString::Chunk &C) {
          return C.Kind == CodeCompletionString::CK_Placeholder;
        });
  }
  unsigned SnippetArg = 0;
  bool HadObjCArguments = false;
  bool HadInformativeChunks = false;
  for (const auto &Chunk : CCS) {
    // Informative qualifier chunks only clutter completion results, skip
    // them.
    if (isInformativeQualifierChunk(Chunk))
      continue;

    switch (Chunk.Kind) {
    case CodeCompletionString::CK_TypedText:
      // The typed-text chunk is the actual name. We don't record this chunk.
      // C++:
      //   In general our string looks like <qualifiers><name><signature>.
      //   So once we see the name, any text we recorded so far should be
      //   reclassified as qualifiers.
      //
      // Objective-C:
      //   Objective-C methods expressions may have multiple typed-text chunks,
      //   so we must treat them carefully. For Objective-C methods, all
      //   typed-text and informative chunks will end in ':' (unless there are
      //   no arguments, in which case we can safely treat them as C++).
      //
      //   Completing a method declaration itself (not a method expression) is
      //   similar except that we use the `RequiredQualifiers` to store the
      //   text before the selector, e.g. `- (void)`.
      if (!llvm::StringRef(Chunk.Text).endswith(":")) { // Treat as C++.
        if (RequiredQualifiers)
          *RequiredQualifiers = std::move(*Signature);
        Signature->clear();
        Snippet->clear();
      } else { // Objective-C method with args.
        // If this is the first TypedText to the Objective-C method, discard any
        // text that we've previously seen (such as previous parameter selector,
        // which will be marked as Informative text).
        //
        // TODO: Make previous parameters part of the signature for Objective-C
        // methods.
        if (!HadObjCArguments) {
          HadObjCArguments = true;
          // If we have no previous informative chunks (informative selector
          // fragments in practice), we treat any previous chunks as
          // `RequiredQualifiers` so they will be added as a prefix during the
          // completion.
          //
          // e.g. to complete `- (void)doSomething:(id)argument`:
          // - Completion name: `doSomething:`
          // - RequiredQualifiers: `- (void)`
          // - Snippet/Signature suffix: `(id)argument`
          //
          // This differs from the case when we're completing a method
          // expression with a previous informative selector fragment.
          //
          // e.g. to complete `[self doSomething:nil ^somethingElse:(id)]`:
          // - Previous Informative Chunk: `doSomething:`
          // - Completion name: `somethingElse:`
          // - Snippet/Signature suffix: `(id)`
          if (!HadInformativeChunks) {
            if (RequiredQualifiers)
              *RequiredQualifiers = std::move(*Signature);
            Snippet->clear();
          }
          Signature->clear();
        } else { // Subsequent argument, considered part of snippet/signature.
          *Signature += Chunk.Text;
          *Snippet += Chunk.Text;
        }
      }
      break;
    case CodeCompletionString::CK_Text:
      *Signature += Chunk.Text;
      *Snippet += Chunk.Text;
      break;
    case CodeCompletionString::CK_Optional:
      assert(Chunk.Optional);      
      // No need to create placeholders for default arguments in Snippet.
      appendOptionalChunk(*Chunk.Optional, Signature);
      break;
    case CodeCompletionString::CK_Placeholder:
      *Signature += Chunk.Text;
      ++SnippetArg;
      *Snippet +=
          "${" +
          std::to_string(SnippetArg == CursorSnippetArg ? 0 : SnippetArg) + ':';
      appendEscapeSnippet(Chunk.Text, Snippet);
      *Snippet += '}';
      break;
    case CodeCompletionString::CK_Informative:
      HadInformativeChunks = true;
      // For example, the word "const" for a const method, or the name of
      // the base class for methods that are part of the base class.
      *Signature += Chunk.Text;
      // Don't put the informative chunks in the snippet.
      break;
    case CodeCompletionString::CK_ResultType:
      // This is not part of the signature.
      break;
    case CodeCompletionString::CK_CurrentParameter:
      // This should never be present while collecting completion items,
      // only while collecting overload candidates.
      llvm_unreachable("Unexpected CK_CurrentParameter while collecting "
                       "CompletionItems");
      break;
    case CodeCompletionString::CK_LeftParen:
    case CodeCompletionString::CK_RightParen:
    case CodeCompletionString::CK_LeftBracket:
    case CodeCompletionString::CK_RightBracket:
    case CodeCompletionString::CK_LeftBrace:
    case CodeCompletionString::CK_RightBrace:
    case CodeCompletionString::CK_LeftAngle:
    case CodeCompletionString::CK_RightAngle:
    case CodeCompletionString::CK_Comma:
    case CodeCompletionString::CK_Colon:
    case CodeCompletionString::CK_SemiColon:
    case CodeCompletionString::CK_Equal:
    case CodeCompletionString::CK_HorizontalSpace:
      *Signature += Chunk.Text;
      *Snippet += Chunk.Text;
      break;
    case CodeCompletionString::CK_VerticalSpace:
      *Snippet += Chunk.Text;
      // Don't even add a space to the signature.
      break;
    }
  }
}

std::string formatDocumentation(const CodeCompletionString &CCS,
                                llvm::StringRef DocComment) {
  // Things like __attribute__((nonnull(1,3))) and [[noreturn]]. Present this
  // information in the documentation field.
  std::string Result;
  const unsigned AnnotationCount = CCS.getAnnotationCount();
  if (AnnotationCount > 0) {
    Result += "Annotation";
    if (AnnotationCount == 1) {
      Result += ": ";
    } else /* AnnotationCount > 1 */ {
      Result += "s: ";
    }
    for (unsigned I = 0; I < AnnotationCount; ++I) {
      Result += CCS.getAnnotation(I);
      Result.push_back(I == AnnotationCount - 1 ? '\n' : ' ');
    }
  }
  // Add brief documentation (if there is any).
  if (!DocComment.empty()) {
    if (!Result.empty()) {
      // This means we previously added annotations. Add an extra newline
      // character to make the annotations stand out.
      Result.push_back('\n');
    }
    Result += DocComment;
  }
  return Result;
}

std::string getReturnType(const CodeCompletionString &CCS) {
  for (const auto &Chunk : CCS)
    if (Chunk.Kind == CodeCompletionString::CK_ResultType)
      return Chunk.Text;
  return "";
}

} // namespace clangd
} // namespace clang
