//===--- LineList.cpp - Data structures for Markup parsing ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/AST/RawComment.h"
#include "swift/Basic/PrimitiveParsing.h"
#include "swift/Markup/LineList.h"
#include "swift/Markup/Markup.h"

using namespace swift;
using namespace markup;

std::string LineList::str() const {
  std::string Result;
  llvm::raw_string_ostream Stream(Result);
  if (Lines.empty())
    return "";

  auto FirstLine = Lines.begin();
  while (FirstLine->Text.empty() && FirstLine != Lines.end())
    ++FirstLine;

  if (FirstLine == Lines.end())
    return "";

  auto InitialIndentation = measureIndentation(FirstLine->Text);

  for (auto Line = FirstLine; Line != Lines.end(); ++Line) {
    auto Drop = std::min(InitialIndentation, Line->FirstNonspaceOffset);
    Stream << Line->Text.drop_front(Drop) << "\n";
  }

  Stream.flush();
  return Result;
}

size_t swift::markup::measureIndentation(StringRef Text) {
  size_t Col = 0;
  for (size_t i = 0, e = Text.size(); i != e; ++i) {
    if (Text[i] == ' ' || Text[i] == '\v' || Text[i] == '\f') {
      Col++;
      continue;
    }

    if (Text[i] == '\t') {
      Col += ((i + 8) / 8) * 8;
      continue;
    }
    return i;
  }
  return Text.size();
}

void LineListBuilder::addLine(llvm::StringRef Text, swift::SourceRange Range) {
  Lines.push_back({Text, Range});
}

LineList LineListBuilder::takeLineList() const {
  return LineList(Context.allocateCopy(ArrayRef<Line>(Lines)));
}

static unsigned measureASCIIArt(StringRef S, unsigned NumLeadingSpaces) {
  StringRef Spaces = S.substr(0, NumLeadingSpaces);
  if (Spaces.size() != NumLeadingSpaces)
    return 0;
  if (Spaces.find_first_not_of(' ') != StringRef::npos)
    return 0;

  S = S.drop_front(NumLeadingSpaces);

  if (S.startswith(" * "))
    return NumLeadingSpaces + 3;
  if (S.startswith(" *\n") || S.startswith(" *\n\r"))
    return NumLeadingSpaces + 2;
  return 0;
}

LineList MarkupContext::getLineList(swift::RawComment RC) {
  LineListBuilder Builder(*this);

  for (const auto &C : RC.Comments) {
    if (C.isLine()) {
      // Skip comment marker.
      unsigned CommentMarkerBytes = 2 + (C.isOrdinary() ? 0 : 1);
      StringRef Cleaned = C.RawText.drop_front(CommentMarkerBytes);

      // Drop trailing newline.
      Cleaned = Cleaned.rtrim("\n\r");
      auto CleanedStartLoc =
          C.Range.getStart().getAdvancedLocOrInvalid(CommentMarkerBytes);
      auto CleanedEndLoc =
          C.Range.getStart().getAdvancedLocOrInvalid(Cleaned.size());
      Builder.addLine(Cleaned, { CleanedStartLoc, CleanedEndLoc });
    } else {
      // Skip comment markers at the beginning and at the end.
      unsigned CommentMarkerBytes = 2 + (C.isOrdinary() ? 0 : 1);
      StringRef Cleaned = C.RawText.drop_front(CommentMarkerBytes);

      if (Cleaned.endswith("*/"))
        Cleaned = Cleaned.drop_back(2);
      else if (Cleaned.endswith("/"))
        Cleaned = Cleaned.drop_back(1);

      swift::SourceLoc CleanedStartLoc =
          C.Range.getStart().getAdvancedLocOrInvalid(CommentMarkerBytes);

      // Determine if we have leading decorations in this block comment.
      bool HasASCIIArt = false;
      if (swift::startsWithNewline(Cleaned)) {
        Builder.addLine(Cleaned.substr(0, 0), { C.Range.getStart(),
                                                C.Range.getStart() });
        unsigned NewlineBytes = swift::measureNewline(Cleaned);
        Cleaned = Cleaned.drop_front(NewlineBytes);
        CleanedStartLoc = CleanedStartLoc.getAdvancedLocOrInvalid(NewlineBytes);
        HasASCIIArt = measureASCIIArt(Cleaned, C.StartColumn - 1) != 0;
      }

      while (!Cleaned.empty()) {
        size_t Pos = Cleaned.find_first_of("\n\r");
        if (Pos == StringRef::npos)
          Pos = Cleaned.size();

        // Skip over ASCII art, if present.
        if (HasASCIIArt)
          if (unsigned ASCIIArtBytes =
              measureASCIIArt(Cleaned, C.StartColumn - 1)) {
            Cleaned = Cleaned.drop_front(ASCIIArtBytes);
            CleanedStartLoc =
            CleanedStartLoc.getAdvancedLocOrInvalid(ASCIIArtBytes);
            Pos -= ASCIIArtBytes;
          }

        StringRef Line = Cleaned.substr(0, Pos);
        auto CleanedEndLoc = CleanedStartLoc.getAdvancedLocOrInvalid(Pos);

        Cleaned = Cleaned.drop_front(Pos);
        unsigned NewlineBytes = swift::measureNewline(Cleaned);
        Cleaned = Cleaned.drop_front(NewlineBytes);
        Pos += NewlineBytes;
        CleanedStartLoc = CleanedStartLoc.getAdvancedLocOrInvalid(Pos);

        Builder.addLine(Line, { CleanedStartLoc, CleanedEndLoc });
      }
    }
  }
  return Builder.takeLineList();
}

LineList LineList::subListWithRange(MarkupContext &MC, size_t StartLine,
                                    size_t EndLine, size_t StartColumn,
                                    size_t EndColumn) const {
  auto TrimmedLines = ArrayRef<Line>(Lines.begin() + StartLine,
                                     Lines.begin() + EndLine);

  LineListBuilder Builder(MC);
  if (TrimmedLines.empty())
    return LineList();

  auto FirstLine = TrimmedLines.begin();
  auto End = TrimmedLines.end();
  auto LastLine = End - 1;

  for (auto Line = FirstLine; Line != End; ++Line) {
    auto T = Line->Text;
    auto RangeStart = Line->Range.Start;
    auto RangeEnd = Line->Range.End;

    if (Line == LastLine) {
      T = T.drop_back(T.size() - EndColumn);
      RangeEnd = RangeStart.getAdvancedLocOrInvalid(EndColumn);
    }

    if (Line == FirstLine) {
      T = T.drop_front(StartColumn);
      RangeStart = RangeStart.getAdvancedLocOrInvalid(StartColumn);
    }

    Builder.addLine(T, {RangeStart, RangeEnd});
  }

  return Builder.takeLineList();
}
