//===--- 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/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;
      if (SnippetArg == CursorSnippetArg) {
        // We'd like to make $0 a placeholder too, but vscode does not support
        // this (https://github.com/microsoft/vscode/issues/152837).
        *Snippet += "$0";
      } else {
        *Snippet += "${" + std::to_string(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
