/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmDocumentationFormatter.h"

#include "cmDocumentationEntry.h"
#include "cmDocumentationSection.h"

#include <ostream>
#include <string.h>
#include <string>
#include <vector>

cmDocumentationFormatter::cmDocumentationFormatter()
  : TextWidth(77)
  , TextIndent("")
{
}

cmDocumentationFormatter::~cmDocumentationFormatter()
{
}

void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
                                              const char* text)
{
  if (!text) {
    return;
  }
  const char* ptr = text;
  while (*ptr) {
    // Any ptrs starting in a space are treated as preformatted text.
    std::string preformatted;
    while (*ptr == ' ') {
      for (char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) {
        preformatted.append(1, ch);
      }
      if (*ptr) {
        ++ptr;
        preformatted.append(1, '\n');
      }
    }
    if (!preformatted.empty()) {
      this->PrintPreformatted(os, preformatted.c_str());
    }

    // Other ptrs are treated as paragraphs.
    std::string paragraph;
    for (char ch = *ptr; ch && ch != '\n'; ++ptr, ch = *ptr) {
      paragraph.append(1, ch);
    }
    if (*ptr) {
      ++ptr;
      paragraph.append(1, '\n');
    }
    if (!paragraph.empty()) {
      this->PrintParagraph(os, paragraph.c_str());
    }
  }
}

void cmDocumentationFormatter::PrintPreformatted(std::ostream& os,
                                                 const char* text)
{
  bool newline = true;
  for (const char* ptr = text; *ptr; ++ptr) {
    if (newline && *ptr != '\n') {
      os << this->TextIndent;
      newline = false;
    }
    os << *ptr;
    if (*ptr == '\n') {
      newline = true;
    }
  }
  os << "\n";
}

void cmDocumentationFormatter::PrintParagraph(std::ostream& os,
                                              const char* text)
{
  os << this->TextIndent;
  this->PrintColumn(os, text);
  os << "\n";
}

void cmDocumentationFormatter::SetIndent(const char* indent)
{
  this->TextIndent = indent;
}

void cmDocumentationFormatter::PrintColumn(std::ostream& os, const char* text)
{
  // Print text arranged in an indented column of fixed witdh.
  const char* l = text;
  long column = 0;
  bool newSentence = false;
  bool firstLine = true;
  int width = this->TextWidth - static_cast<int>(strlen(this->TextIndent));

  // Loop until the end of the text.
  while (*l) {
    // Parse the next word.
    const char* r = l;
    while (*r && (*r != '\n') && (*r != ' ')) {
      ++r;
    }

    // Does it fit on this line?
    if (r - l < (width - column - (newSentence ? 1 : 0))) {
      // Word fits on this line.
      if (r > l) {
        if (column) {
          // Not first word on line.  Separate from the previous word
          // by a space, or two if this is a new sentence.
          if (newSentence) {
            os << "  ";
            column += 2;
          } else {
            os << " ";
            column += 1;
          }
        } else {
          // First word on line.  Print indentation unless this is the
          // first line.
          os << (firstLine ? "" : this->TextIndent);
        }

        // Print the word.
        os.write(l, static_cast<long>(r - l));
        newSentence = (*(r - 1) == '.');
      }

      if (*r == '\n') {
        // Text provided a newline.  Start a new line.
        os << "\n";
        ++r;
        column = 0;
        firstLine = false;
      } else {
        // No provided newline.  Continue this line.
        column += static_cast<long>(r - l);
      }
    } else {
      // Word does not fit on this line.  Start a new line.
      os << "\n";
      firstLine = false;
      if (r > l) {
        os << this->TextIndent;
        os.write(l, static_cast<long>(r - l));
        column = static_cast<long>(r - l);
        newSentence = (*(r - 1) == '.');
      } else {
        column = 0;
      }
    }

    // Move to beginning of next word.  Skip over whitespace.
    l = r;
    while (*l == ' ') {
      ++l;
    }
  }
}

void cmDocumentationFormatter::PrintSection(
  std::ostream& os, cmDocumentationSection const& section)
{
  os << section.GetName() << "\n";

  const std::vector<cmDocumentationEntry>& entries = section.GetEntries();
  for (cmDocumentationEntry const& entry : entries) {
    if (!entry.Name.empty()) {
      os << "  " << entry.Name;
      this->TextIndent = "                                 ";
      int align = static_cast<int>(strlen(this->TextIndent)) - 4;
      for (int i = static_cast<int>(entry.Name.size()); i < align; ++i) {
        os << " ";
      }
      if (entry.Name.size() > strlen(this->TextIndent) - 4) {
        os << "\n";
        os.write(this->TextIndent, strlen(this->TextIndent) - 2);
      }
      os << "= ";
      this->PrintColumn(os, entry.Brief.c_str());
      os << "\n";
    } else {
      os << "\n";
      this->TextIndent = "";
      this->PrintFormatted(os, entry.Brief.c_str());
    }
  }
  os << "\n";
}
