//===- lib/DebugInfo/Symbolize/Markup.cpp ------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines the log symbolizer markup data model and parser.
///
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/Symbolize/Markup.h"

#include "llvm/ADT/STLExtras.h"

namespace llvm {
namespace symbolize {

// Matches the following:
//   "\033[0m"
//   "\033[1m"
//   "\033[30m" -- "\033[37m"
static const char SGRSyntaxStr[] = "\033\\[([0-1]|3[0-7])m";

MarkupParser::MarkupParser(StringSet<> MultilineTags)
    : MultilineTags(std::move(MultilineTags)), SGRSyntax(SGRSyntaxStr) {}

static StringRef takeTo(StringRef Str, StringRef::iterator Pos) {
  return Str.take_front(Pos - Str.begin());
}
static void advanceTo(StringRef &Str, StringRef::iterator Pos) {
  Str = Str.drop_front(Pos - Str.begin());
}

void MarkupParser::parseLine(StringRef Line) {
  Buffer.clear();
  NextIdx = 0;
  FinishedMultiline.clear();
  this->Line = Line;
}

std::optional<MarkupNode> MarkupParser::nextNode() {
  // Pull something out of the buffer if possible.
  if (!Buffer.empty()) {
    if (NextIdx < Buffer.size())
      return std::move(Buffer[NextIdx++]);
    NextIdx = 0;
    Buffer.clear();
  }

  // The buffer is empty, so parse the next bit of the line.

  if (Line.empty())
    return std::nullopt;

  if (!InProgressMultiline.empty()) {
    if (std::optional<StringRef> MultilineEnd = parseMultiLineEnd(Line)) {
      llvm::append_range(InProgressMultiline, *MultilineEnd);
      assert(FinishedMultiline.empty() &&
             "At most one multi-line element can be finished at a time.");
      FinishedMultiline.swap(InProgressMultiline);
      // Parse the multi-line element as if it were contiguous.
      advanceTo(Line, MultilineEnd->end());
      return *parseElement(FinishedMultiline);
    }

    // The whole line is part of the multi-line element.
    llvm::append_range(InProgressMultiline, Line);
    Line = Line.drop_front(Line.size());
    return std::nullopt;
  }

  // Find the first valid markup element, if any.
  if (std::optional<MarkupNode> Element = parseElement(Line)) {
    parseTextOutsideMarkup(takeTo(Line, Element->Text.begin()));
    Buffer.push_back(std::move(*Element));
    advanceTo(Line, Element->Text.end());
    return nextNode();
  }

  // Since there were no valid elements remaining, see if the line opens a
  // multi-line element.
  if (std::optional<StringRef> MultilineBegin = parseMultiLineBegin(Line)) {
    // Emit any text before the element.
    parseTextOutsideMarkup(takeTo(Line, MultilineBegin->begin()));

    // Begin recording the multi-line element.
    llvm::append_range(InProgressMultiline, *MultilineBegin);
    Line = Line.drop_front(Line.size());
    return nextNode();
  }

  // The line doesn't contain any more markup elements, so emit it as text.
  parseTextOutsideMarkup(Line);
  Line = Line.drop_front(Line.size());
  return nextNode();
}

void MarkupParser::flush() {
  Buffer.clear();
  NextIdx = 0;
  Line = {};
  if (InProgressMultiline.empty())
    return;
  FinishedMultiline.swap(InProgressMultiline);
  parseTextOutsideMarkup(FinishedMultiline);
}

// Finds and returns the next valid markup element in the given line. Returns
// std::nullopt if the line contains no valid elements.
std::optional<MarkupNode> MarkupParser::parseElement(StringRef Line) {
  while (true) {
    // Find next element using begin and end markers.
    size_t BeginPos = Line.find("{{{");
    if (BeginPos == StringRef::npos)
      return std::nullopt;
    size_t EndPos = Line.find("}}}", BeginPos + 3);
    if (EndPos == StringRef::npos)
      return std::nullopt;
    EndPos += 3;
    MarkupNode Element;
    Element.Text = Line.slice(BeginPos, EndPos);
    Line = Line.substr(EndPos);

    // Parse tag.
    StringRef Content = Element.Text.drop_front(3).drop_back(3);
    StringRef FieldsContent;
    std::tie(Element.Tag, FieldsContent) = Content.split(':');
    if (Element.Tag.empty())
      continue;

    // Parse fields.
    if (!FieldsContent.empty())
      FieldsContent.split(Element.Fields, ":");
    else if (Content.back() == ':')
      Element.Fields.push_back(FieldsContent);

    return Element;
  }
}

static MarkupNode textNode(StringRef Text) {
  MarkupNode Node;
  Node.Text = Text;
  return Node;
}

// Parses a region of text known to be outside any markup elements. Such text
// may still contain SGR control codes, so the region is further subdivided into
// control codes and true text regions.
void MarkupParser::parseTextOutsideMarkup(StringRef Text) {
  if (Text.empty())
    return;
  SmallVector<StringRef> Matches;
  while (SGRSyntax.match(Text, &Matches)) {
    // Emit any text before the SGR element.
    if (Matches.begin()->begin() != Text.begin())
      Buffer.push_back(textNode(takeTo(Text, Matches.begin()->begin())));

    Buffer.push_back(textNode(*Matches.begin()));
    advanceTo(Text, Matches.begin()->end());
  }
  if (!Text.empty())
    Buffer.push_back(textNode(Text));
}

// Given that a line doesn't contain any valid markup, see if it ends with the
// start of a multi-line element. If so, returns the beginning.
std::optional<StringRef> MarkupParser::parseMultiLineBegin(StringRef Line) {
  // A multi-line begin marker must be the last one on the line.
  size_t BeginPos = Line.rfind("{{{");
  if (BeginPos == StringRef::npos)
    return std::nullopt;
  size_t BeginTagPos = BeginPos + 3;

  // If there are any end markers afterwards, the begin marker cannot belong to
  // a multi-line element.
  size_t EndPos = Line.find("}}}", BeginTagPos);
  if (EndPos != StringRef::npos)
    return std::nullopt;

  // Check whether the tag is registered multi-line.
  size_t EndTagPos = Line.find(':', BeginTagPos);
  if (EndTagPos == StringRef::npos)
    return std::nullopt;
  StringRef Tag = Line.slice(BeginTagPos, EndTagPos);
  if (!MultilineTags.contains(Tag))
    return std::nullopt;
  return Line.substr(BeginPos);
}

// See if the line begins with the ending of an in-progress multi-line element.
// If so, return the ending.
std::optional<StringRef> MarkupParser::parseMultiLineEnd(StringRef Line) {
  size_t EndPos = Line.find("}}}");
  if (EndPos == StringRef::npos)
    return std::nullopt;
  return Line.take_front(EndPos + 3);
}

} // end namespace symbolize
} // end namespace llvm
