//===--- FormattedString.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 "FormattedString.h"
#include "clang/Basic/CharInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include <cstddef>
#include <string>

namespace clang {
namespace clangd {

namespace {
/// Escape a markdown text block. Ensures the punctuation will not introduce
/// any of the markdown constructs.
static std::string renderText(llvm::StringRef Input) {
  // Escaping ASCII punctiation ensures we can't start a markdown construct.
  constexpr llvm::StringLiteral Punctuation =
      R"txt(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)txt";

  std::string R;
  for (size_t From = 0; From < Input.size();) {
    size_t Next = Input.find_first_of(Punctuation, From);
    R += Input.substr(From, Next - From);
    if (Next == llvm::StringRef::npos)
      break;
    R += "\\";
    R += Input[Next];

    From = Next + 1;
  }
  return R;
}

/// Renders \p Input as an inline block of code in markdown. The returned value
/// is surrounded by backticks and the inner contents are properly escaped.
static std::string renderInlineBlock(llvm::StringRef Input) {
  std::string R;
  // Double all backticks to make sure we don't close the inline block early.
  for (size_t From = 0; From < Input.size();) {
    size_t Next = Input.find("`", From);
    R += Input.substr(From, Next - From);
    if (Next == llvm::StringRef::npos)
      break;
    R += "``"; // double the found backtick.

    From = Next + 1;
  }
  // If results starts with a backtick, add spaces on both sides. The spaces
  // are ignored by markdown renderers.
  if (llvm::StringRef(R).startswith("`") || llvm::StringRef(R).endswith("`"))
    return "` " + std::move(R) + " `";
  // Markdown render should ignore first and last space if both are there. We
  // add an extra pair of spaces in that case to make sure we render what the
  // user intended.
  if (llvm::StringRef(R).startswith(" ") && llvm::StringRef(R).endswith(" "))
    return "` " + std::move(R) + " `";
  return "`" + std::move(R) + "`";
}
/// Render \p Input as markdown code block with a specified \p Language. The
/// result is surrounded by >= 3 backticks. Although markdown also allows to use
/// '~' for code blocks, they are never used.
static std::string renderCodeBlock(llvm::StringRef Input,
                                   llvm::StringRef Language) {
  // Count the maximum number of consecutive backticks in \p Input. We need to
  // start and end the code block with more.
  unsigned MaxBackticks = 0;
  unsigned Backticks = 0;
  for (char C : Input) {
    if (C == '`') {
      ++Backticks;
      continue;
    }
    MaxBackticks = std::max(MaxBackticks, Backticks);
    Backticks = 0;
  }
  MaxBackticks = std::max(Backticks, MaxBackticks);
  // Use the corresponding number of backticks to start and end a code block.
  std::string BlockMarker(/*Repeat=*/std::max(3u, MaxBackticks + 1), '`');
  return BlockMarker + Language.str() + "\n" + Input.str() + "\n" + BlockMarker;
}

} // namespace

void FormattedString::appendText(std::string Text) {
  Chunk C;
  C.Kind = ChunkKind::PlainText;
  C.Contents = Text;
  Chunks.push_back(C);
}

void FormattedString::appendCodeBlock(std::string Code, std::string Language) {
  Chunk C;
  C.Kind = ChunkKind::CodeBlock;
  C.Contents = std::move(Code);
  C.Language = std::move(Language);
  Chunks.push_back(std::move(C));
}

void FormattedString::appendInlineCode(std::string Code) {
  Chunk C;
  C.Kind = ChunkKind::InlineCodeBlock;
  C.Contents = std::move(Code);
  Chunks.push_back(std::move(C));
}

std::string FormattedString::renderAsMarkdown() const {
  std::string R;
  auto EnsureWhitespace = [&R]() {
    // Adds a space for nicer rendering.
    if (!R.empty() && !isWhitespace(R.back()))
      R += " ";
  };
  for (const auto &C : Chunks) {
    switch (C.Kind) {
    case ChunkKind::PlainText:
      if (!C.Contents.empty() && !isWhitespace(C.Contents.front()))
        EnsureWhitespace();
      R += renderText(C.Contents);
      continue;
    case ChunkKind::InlineCodeBlock:
      EnsureWhitespace();
      R += renderInlineBlock(C.Contents);
      continue;
    case ChunkKind::CodeBlock:
      if (!R.empty() && !llvm::StringRef(R).endswith("\n"))
        R += "\n";
      R += renderCodeBlock(C.Contents, C.Language);
      R += "\n";
      continue;
    }
    llvm_unreachable("unhanlded ChunkKind");
  }
  return R;
}

std::string FormattedString::renderAsPlainText() const {
  std::string R;
  auto EnsureWhitespace = [&]() {
    if (R.empty() || isWhitespace(R.back()))
      return;
    R += " ";
  };
  Optional<bool> LastWasBlock;
  for (const auto &C : Chunks) {
    bool IsBlock = C.Kind == ChunkKind::CodeBlock;
    if (LastWasBlock.hasValue() && (IsBlock || *LastWasBlock))
      R += "\n\n";
    LastWasBlock = IsBlock;

    switch (C.Kind) {
    case ChunkKind::PlainText:
      EnsureWhitespace();
      R += C.Contents;
      break;
    case ChunkKind::InlineCodeBlock:
      EnsureWhitespace();
      R += C.Contents;
      break;
    case ChunkKind::CodeBlock:
      R += C.Contents;
      break;
    }
    // Trim trailing whitespace in chunk.
    while (!R.empty() && isWhitespace(R.back()))
      R.pop_back();
  }
  return R;
}

std::string FormattedString::renderForTests() const {
  std::string R;
  for (const auto &C : Chunks) {
    switch (C.Kind) {
    case ChunkKind::PlainText:
      R += "text[" + C.Contents + "]";
      break;
    case ChunkKind::InlineCodeBlock:
      R += "code[" + C.Contents + "]";
      break;
    case ChunkKind::CodeBlock:
      if (!R.empty())
        R += "\n";
      R += llvm::formatv("codeblock({0}) [\n{1}\n]\n", C.Language, C.Contents);
      break;
    }
  }
  while (!R.empty() && isWhitespace(R.back()))
    R.pop_back();
  return R;
}
} // namespace clangd
} // namespace clang
