/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2013 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmRST.h"

#include "cmSystemTools.h"
#include "cmAlgorithms.h"
#include "cmVersion.h"
#include <cmsys/FStream.hxx>
#include <ctype.h>

//----------------------------------------------------------------------------
cmRST::cmRST(std::ostream& os, std::string const& docroot):
  OS(os),
  DocRoot(docroot),
  IncludeDepth(0),
  OutputLinePending(false),
  LastLineEndedInColonColon(false),
  Markup(MarkupNone),
  Directive(DirectiveNone),
  CMakeDirective("^.. (cmake:)?("
                 "command|variable"
                 ")::[ \t]+([^ \t\n]+)$"),
  CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$"),
  ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$"),
  CodeBlockDirective("^.. code-block::[ \t]*(.*)$"),
  ReplaceDirective("^.. (\\|[^|]+\\|) replace::[ \t]*(.*)$"),
  IncludeDirective("^.. include::[ \t]+([^ \t\n]+)$"),
  TocTreeDirective("^.. toctree::[ \t]*(.*)$"),
  ProductionListDirective("^.. productionlist::[ \t]*(.*)$"),
  NoteDirective("^.. note::[ \t]*(.*)$"),
  ModuleRST("^#\\[(=*)\\[\\.rst:$"),
  CMakeRole("(:cmake)?:("
            "command|generator|variable|module|policy|"
            "prop_cache|prop_dir|prop_gbl|prop_inst|prop_sf|"
            "prop_test|prop_tgt|"
            "manual"
            "):`(<*([^`<]|[^` \t]<)*)([ \t]+<[^`]*>)?`"),
  Substitution("(^|[^A-Za-z0-9_])"
               "((\\|[^| \t\r\n]([^|\r\n]*[^| \t\r\n])?\\|)(__|_|))"
               "([^A-Za-z0-9_]|$)")
{
  this->Replace["|release|"] = cmVersion::GetCMakeVersion();
}

//----------------------------------------------------------------------------
bool cmRST::ProcessFile(std::string const& fname, bool isModule)
{
  cmsys::ifstream fin(fname.c_str());
  if(fin)
    {
    this->DocDir = cmSystemTools::GetFilenamePath(fname);
    if(isModule)
      {
      this->ProcessModule(fin);
      }
    else
      {
      this->ProcessRST(fin);
      }
    this->OutputLinePending = true;
    return true;
    }
  return false;
}

//----------------------------------------------------------------------------
void cmRST::ProcessRST(std::istream& is)
{
  std::string line;
  while(cmSystemTools::GetLineFromStream(is, line))
    {
    this->ProcessLine(line);
    }
  this->Reset();
}

//----------------------------------------------------------------------------
void cmRST::ProcessModule(std::istream& is)
{
  std::string line;
  std::string rst;
  while(cmSystemTools::GetLineFromStream(is, line))
    {
    if(!rst.empty() && rst != "#")
      {
      // Bracket mode: check for end bracket
      std::string::size_type pos = line.find(rst);
      if(pos == line.npos)
        {
        this->ProcessLine(line);
        }
      else
        {
        if(line[0] != '#')
          {
          this->ProcessLine(line.substr(0, pos));
          }
        rst = "";
        this->Reset();
        this->OutputLinePending = true;
        }
      }
    else
      {
      // Line mode: check for .rst start (bracket or line)
      if(rst == "#")
        {
        if(line == "#")
          {
          this->ProcessLine("");
          continue;
          }
        else if(line.substr(0, 2) == "# ")
          {
          this->ProcessLine(line.substr(2, line.npos));
          continue;
          }
        else
          {
          rst = "";
          this->Reset();
          this->OutputLinePending = true;
          }
        }
      if(line == "#.rst:")
        {
        rst = "#";
        }
      else if(this->ModuleRST.find(line))
        {
        rst = "]" + this->ModuleRST.match(1) + "]";
        }
      }
    }
  if(rst == "#")
    {
    this->Reset();
    }
}

//----------------------------------------------------------------------------
void cmRST::Reset()
{
  if(!this->MarkupLines.empty())
    {
    this->UnindentLines(this->MarkupLines);
    }
  switch(this->Directive)
    {
    case DirectiveNone: break;
    case DirectiveParsedLiteral: this->ProcessDirectiveParsedLiteral(); break;
    case DirectiveLiteralBlock: this->ProcessDirectiveLiteralBlock(); break;
    case DirectiveCodeBlock: this->ProcessDirectiveCodeBlock(); break;
    case DirectiveReplace: this->ProcessDirectiveReplace(); break;
    case DirectiveTocTree: this->ProcessDirectiveTocTree(); break;
    }
  this->Markup = MarkupNone;
  this->Directive = DirectiveNone;
  this->MarkupLines.clear();
}

//----------------------------------------------------------------------------
void cmRST::ProcessLine(std::string const& line)
{
  bool lastLineEndedInColonColon = this->LastLineEndedInColonColon;
  this->LastLineEndedInColonColon = false;

  // A line starting in .. is an explicit markup start.
  if(line == ".." || (line.size() >= 3 && line[0] == '.' &&
                      line[1] == '.' && isspace(line[2])))
    {
    this->Reset();
    this->Markup = (line.find_first_not_of(" \t", 2) == line.npos ?
                    MarkupEmpty : MarkupNormal);
    if(this->CMakeDirective.find(line))
      {
      // Output cmake domain directives and their content normally.
      this->NormalLine(line);
      }
    else if(this->CMakeModuleDirective.find(line))
      {
      // Process cmake-module directive: scan .cmake file comments.
      std::string file = this->CMakeModuleDirective.match(1);
      if(file.empty() || !this->ProcessInclude(file, IncludeModule))
        {
        this->NormalLine(line);
        }
      }
    else if(this->ParsedLiteralDirective.find(line))
      {
      // Record the literal lines to output after whole block.
      this->Directive = DirectiveParsedLiteral;
      this->MarkupLines.push_back(this->ParsedLiteralDirective.match(1));
      }
    else if(this->CodeBlockDirective.find(line))
      {
      // Record the literal lines to output after whole block.
      // Ignore the language spec and record the opening line as blank.
      this->Directive = DirectiveCodeBlock;
      this->MarkupLines.push_back("");
      }
    else if(this->ReplaceDirective.find(line))
      {
      // Record the replace directive content.
      this->Directive = DirectiveReplace;
      this->ReplaceName = this->ReplaceDirective.match(1);
      this->MarkupLines.push_back(this->ReplaceDirective.match(2));
      }
    else if(this->IncludeDirective.find(line))
      {
      // Process the include directive or output the directive and its
      // content normally if it fails.
      std::string file = this->IncludeDirective.match(1);
      if(file.empty() || !this->ProcessInclude(file, IncludeNormal))
        {
        this->NormalLine(line);
        }
      }
    else if(this->TocTreeDirective.find(line))
      {
      // Record the toctree entries to process after whole block.
      this->Directive = DirectiveTocTree;
      this->MarkupLines.push_back(this->TocTreeDirective.match(1));
      }
    else if(this->ProductionListDirective.find(line))
      {
      // Output productionlist directives and their content normally.
      this->NormalLine(line);
      }
    else if(this->NoteDirective.find(line))
      {
      // Output note directives and their content normally.
      this->NormalLine(line);
      }
    }
  // An explicit markup start followed nothing but whitespace and a
  // blank line does not consume any indented text following.
  else if(this->Markup == MarkupEmpty && line.empty())
    {
    this->NormalLine(line);
    }
  // Indented lines following an explicit markup start are explicit markup.
  else if(this->Markup && (line.empty() || isspace(line[0])))
    {
    this->Markup = MarkupNormal;
    // Record markup lines if the start line was recorded.
    if(!this->MarkupLines.empty())
      {
      this->MarkupLines.push_back(line);
      }
    }
  // A blank line following a paragraph ending in "::" starts a literal block.
  else if(lastLineEndedInColonColon && line.empty())
    {
    // Record the literal lines to output after whole block.
    this->Markup = MarkupNormal;
    this->Directive = DirectiveLiteralBlock;
    this->MarkupLines.push_back("");
    this->OutputLine("", false);
    }
  // Print non-markup lines.
  else
    {
    this->NormalLine(line);
    this->LastLineEndedInColonColon = (line.size() >= 2
      && line[line.size()-2] == ':' && line[line.size()-1] == ':');
    }
}

//----------------------------------------------------------------------------
void cmRST::NormalLine(std::string const& line)
{
  this->Reset();
  this->OutputLine(line, true);
}

//----------------------------------------------------------------------------
void cmRST::OutputLine(std::string const& line_in, bool inlineMarkup)
{
  if(this->OutputLinePending)
    {
    this->OS << "\n";
    this->OutputLinePending = false;
    }
  if(inlineMarkup)
    {
    std::string line = this->ReplaceSubstitutions(line_in);
    std::string::size_type pos = 0;
    while(this->CMakeRole.find(line.c_str()+pos))
      {
      this->OS << line.substr(pos, this->CMakeRole.start());
      std::string text = this->CMakeRole.match(3);
      // If a command reference has no explicit target and
      // no explicit "(...)" then add "()" to the text.
      if(this->CMakeRole.match(2) == "command" &&
         this->CMakeRole.match(5).empty() &&
         text.find_first_of("()") == text.npos)
        {
        text += "()";
        }
      this->OS << "``" << text << "``";
      pos += this->CMakeRole.end();
      }
    this->OS << line.substr(pos) << "\n";
    }
  else
    {
    this->OS << line_in << "\n";
    }
}

//----------------------------------------------------------------------------
std::string cmRST::ReplaceSubstitutions(std::string const& line)
{
  std::string out;
  std::string::size_type pos = 0;
  while(this->Substitution.find(line.c_str()+pos))
    {
    std::string::size_type start = this->Substitution.start(2);
    std::string::size_type end = this->Substitution.end(2);
    std::string substitute = this->Substitution.match(3);
    std::map<std::string, std::string>::iterator
      replace = this->Replace.find(substitute);
    if(replace != this->Replace.end())
      {
      std::pair<std::set<std::string>::iterator, bool> replaced =
        this->Replaced.insert(substitute);
      if(replaced.second)
        {
        substitute = this->ReplaceSubstitutions(replace->second);
        this->Replaced.erase(replaced.first);
        }
      }
    out += line.substr(pos, start);
    out += substitute;
    pos += end;
    }
  out += line.substr(pos);
  return out;
}

//----------------------------------------------------------------------------
void cmRST::OutputMarkupLines(bool inlineMarkup)
{
  for(std::vector<std::string>::iterator i = this->MarkupLines.begin();
      i != this->MarkupLines.end(); ++i)
    {
    std::string line = *i;
    if(!line.empty())
      {
      line = " " + line;
      }
    this->OutputLine(line, inlineMarkup);
    }
  this->OutputLinePending = true;
}

//----------------------------------------------------------------------------
bool cmRST::ProcessInclude(std::string file, IncludeType type)
{
  bool found = false;
  if(this->IncludeDepth < 10)
    {
    cmRST r(this->OS, this->DocRoot);
    r.IncludeDepth = this->IncludeDepth + 1;
    r.OutputLinePending = this->OutputLinePending;
    if(type != IncludeTocTree)
      {
      r.Replace = this->Replace;
      }
    if(file[0] == '/')
      {
      file = this->DocRoot + file;
      }
    else
      {
      file = this->DocDir + "/" + file;
      }
    found = r.ProcessFile(file, type == IncludeModule);
    if(type != IncludeTocTree)
      {
      this->Replace = r.Replace;
      }
    this->OutputLinePending = r.OutputLinePending;
    }
  return found;
}

//----------------------------------------------------------------------------
void cmRST::ProcessDirectiveParsedLiteral()
{
  this->OutputMarkupLines(true);
}

//----------------------------------------------------------------------------
void cmRST::ProcessDirectiveLiteralBlock()
{
  this->OutputMarkupLines(false);
}

//----------------------------------------------------------------------------
void cmRST::ProcessDirectiveCodeBlock()
{
  this->OutputMarkupLines(false);
}

//----------------------------------------------------------------------------
void cmRST::ProcessDirectiveReplace()
{
  // Record markup lines as replacement text.
  std::string& replacement = this->Replace[this->ReplaceName];
  replacement += cmJoin(this->MarkupLines, " ");
  this->ReplaceName = "";
}

//----------------------------------------------------------------------------
void cmRST::ProcessDirectiveTocTree()
{
  // Process documents referenced by toctree directive.
  for(std::vector<std::string>::iterator i = this->MarkupLines.begin();
      i != this->MarkupLines.end(); ++i)
    {
    if(!i->empty() && i->find_first_of(":") == i->npos)
      {
      this->ProcessInclude(*i + ".rst", IncludeTocTree);
      }
    }
}

//----------------------------------------------------------------------------
void cmRST::UnindentLines(std::vector<std::string>& lines)
{
  // Remove the common indentation from the second and later lines.
  std::string indentText;
  std::string::size_type indentEnd = 0;
  bool first = true;
  for(size_t i = 1; i < lines.size(); ++i)
    {
    std::string const& line = lines[i];

    // Do not consider empty lines.
    if(line.empty())
      {
      continue;
      }

    // Record indentation on first non-empty line.
    if(first)
      {
      first = false;
      indentEnd = line.find_first_not_of(" \t");
      indentText = line.substr(0, indentEnd);
      continue;
      }

    // Truncate indentation to match that on this line.
    indentEnd = std::min(indentEnd, line.size());
    for(std::string::size_type j = 0; j != indentEnd; ++j)
      {
      if(line[j] != indentText[j])
        {
        indentEnd = j;
        break;
        }
      }
    }

  // Update second and later lines.
  for(size_t i = 1; i < lines.size(); ++i)
    {
    std::string& line = lines[i];
    if(!line.empty())
      {
      line = line.substr(indentEnd);
      }
    }

  std::vector<std::string>::const_iterator it = lines.begin();
  size_t leadingEmpty = std::distance(it, cmFindNot(lines, std::string()));

  std::vector<std::string>::const_reverse_iterator rit = lines.rbegin();
  size_t trailingEmpty = std::distance(rit,
                            cmFindNot(cmReverseRange(lines), std::string()));

  std::vector<std::string>::iterator contentEnd
      = cmRotate(lines.begin(),
                 lines.begin() + leadingEmpty,
                 lines.end() - trailingEmpty);
  lines.erase(contentEnd, lines.end());
}
