//===-- MDGenerator.cpp - Markdown Generator --------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Generators.h"
#include "Representation.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include <string>

using namespace llvm;

namespace clang {
namespace doc {

// Enum conversion

std::string getAccess(AccessSpecifier AS) {
  switch (AS) {
  case AccessSpecifier::AS_public:
    return "public";
  case AccessSpecifier::AS_protected:
    return "protected";
  case AccessSpecifier::AS_private:
    return "private";
  case AccessSpecifier::AS_none:
    return {};
  }
  llvm_unreachable("Unknown AccessSpecifier");
}

std::string getTagType(TagTypeKind AS) {
  switch (AS) {
  case TagTypeKind::TTK_Class:
    return "class";
  case TagTypeKind::TTK_Union:
    return "union";
  case TagTypeKind::TTK_Interface:
    return "interface";
  case TagTypeKind::TTK_Struct:
    return "struct";
  case TagTypeKind::TTK_Enum:
    return "enum";
  }
  llvm_unreachable("Unknown TagTypeKind");
}

// Markdown generation

std::string genItalic(const Twine &Text) { return "*" + Text.str() + "*"; }

std::string genEmphasis(const Twine &Text) { return "**" + Text.str() + "**"; }

std::string genLink(const Twine &Text, const Twine &Link) {
  return "[" + Text.str() + "](" + Link.str() + ")";
}

std::string genReferenceList(const llvm::SmallVectorImpl<Reference> &Refs) {
  std::string Buffer;
  llvm::raw_string_ostream Stream(Buffer);
  bool First = true;
  for (const auto &R : Refs) {
    if (!First)
      Stream << ", ";
    Stream << R.Name;
    First = false;
  }
  return Stream.str();
}

void writeLine(const Twine &Text, raw_ostream &OS) { OS << Text << "\n"; }

void writeNewLine(raw_ostream &OS) { OS << "\n"; }

void writeHeader(const Twine &Text, unsigned int Num, raw_ostream &OS) {
  OS << std::string(Num, '#') + " " + Text << "\n";
}

void writeFileDefinition(const Location &L, raw_ostream &OS) {
  OS << genItalic("Defined at line " + std::to_string(L.LineNumber) + " of " +
                  L.Filename)
     << "\n";
}

void writeDescription(const CommentInfo &I, raw_ostream &OS) {
  if (I.Kind == "FullComment") {
    for (const auto &Child : I.Children)
      writeDescription(*Child, OS);
  } else if (I.Kind == "ParagraphComment") {
    for (const auto &Child : I.Children)
      writeDescription(*Child, OS);
    writeNewLine(OS);
  } else if (I.Kind == "BlockCommandComment") {
    OS << genEmphasis(I.Name);
    for (const auto &Child : I.Children)
      writeDescription(*Child, OS);
  } else if (I.Kind == "InlineCommandComment") {
    OS << genEmphasis(I.Name) << " " << I.Text;
  } else if (I.Kind == "ParamCommandComment") {
    std::string Direction = I.Explicit ? (" " + I.Direction).str() : "";
    OS << genEmphasis(I.ParamName) << I.Text << Direction << "\n";
  } else if (I.Kind == "TParamCommandComment") {
    std::string Direction = I.Explicit ? (" " + I.Direction).str() : "";
    OS << genEmphasis(I.ParamName) << I.Text << Direction << "\n";
  } else if (I.Kind == "VerbatimBlockComment") {
    for (const auto &Child : I.Children)
      writeDescription(*Child, OS);
  } else if (I.Kind == "VerbatimBlockLineComment") {
    OS << I.Text;
    writeNewLine(OS);
  } else if (I.Kind == "VerbatimLineComment") {
    OS << I.Text;
    writeNewLine(OS);
  } else if (I.Kind == "HTMLStartTagComment") {
    if (I.AttrKeys.size() != I.AttrValues.size())
      return;
    std::string Buffer;
    llvm::raw_string_ostream Attrs(Buffer);
    for (unsigned Idx = 0; Idx < I.AttrKeys.size(); ++Idx)
      Attrs << " \"" << I.AttrKeys[Idx] << "=" << I.AttrValues[Idx] << "\"";

    std::string CloseTag = I.SelfClosing ? "/>" : ">";
    writeLine("<" + I.Name + Attrs.str() + CloseTag, OS);
  } else if (I.Kind == "HTMLEndTagComment") {
    writeLine("</" + I.Name + ">", OS);
  } else if (I.Kind == "TextComment") {
    OS << I.Text;
  } else {
    OS << "Unknown comment kind: " << I.Kind << ".\n";
  }
}

void genMarkdown(const EnumInfo &I, llvm::raw_ostream &OS) {
  if (I.Scoped)
    writeLine("| enum class " + I.Name + " |", OS);
  else
    writeLine("| enum " + I.Name + " |", OS);
  writeLine("--", OS);

  std::string Buffer;
  llvm::raw_string_ostream Members(Buffer);
  if (!I.Members.empty())
    for (const auto &N : I.Members)
      Members << "| " << N << " |\n";
  writeLine(Members.str(), OS);
  if (I.DefLoc)
    writeFileDefinition(I.DefLoc.getValue(), OS);

  for (const auto &C : I.Description)
    writeDescription(C, OS);
}

void genMarkdown(const FunctionInfo &I, llvm::raw_ostream &OS) {
  std::string Buffer;
  llvm::raw_string_ostream Stream(Buffer);
  bool First = true;
  for (const auto &N : I.Params) {
    if (!First)
      Stream << ", ";
    Stream << N.Type.Name + " " + N.Name;
    First = false;
  }
  std::string Access = getAccess(I.Access);
  if (Access != "")
    writeHeader(genItalic(Access) + " " + I.ReturnType.Type.Name + " " + I.Name + "(" + Stream.str() + ")", 3, OS);
  else 
    writeHeader(I.ReturnType.Type.Name + " " + I.Name + "(" + Stream.str() + ")", 3, OS);
  if (I.DefLoc)
    writeFileDefinition(I.DefLoc.getValue(), OS);

  for (const auto &C : I.Description)
    writeDescription(C, OS);
}

void genMarkdown(const NamespaceInfo &I, llvm::raw_ostream &OS) {
  if (I.Name == "")
    writeHeader("Global Namespace", 1, OS);
  else
    writeHeader("namespace " + I.Name, 1, OS);
  writeNewLine(OS);

  if (!I.Description.empty()) {
    for (const auto &C : I.Description)
      writeDescription(C, OS);
    writeNewLine(OS);
  }

  if (!I.ChildNamespaces.empty()) {
    writeHeader("Namespaces", 2, OS);
    for (const auto &R : I.ChildNamespaces)
      writeLine(R.Name, OS);
    writeNewLine(OS);
  }
  if (!I.ChildRecords.empty()) {
    writeHeader("Records", 2, OS);
    for (const auto &R : I.ChildRecords)
      writeLine(R.Name, OS);
    writeNewLine(OS);
  }
  if (!I.ChildFunctions.empty()) {
    writeHeader("Functions", 2, OS);
    for (const auto &F : I.ChildFunctions)
      genMarkdown(F, OS);
    writeNewLine(OS);
  }
  if (!I.ChildEnums.empty()) {
    writeHeader("Enums", 2, OS);
    for (const auto &E : I.ChildEnums)
      genMarkdown(E, OS);
    writeNewLine(OS);
  }
}

void genMarkdown(const RecordInfo &I, llvm::raw_ostream &OS) {
  writeHeader(getTagType(I.TagType) + " " + I.Name, 1, OS);
  if (I.DefLoc)
    writeFileDefinition(I.DefLoc.getValue(), OS);

  if (!I.Description.empty()) {
    for (const auto &C : I.Description)
      writeDescription(C, OS);
    writeNewLine(OS);
  }

  std::string Parents = genReferenceList(I.Parents);
  std::string VParents = genReferenceList(I.VirtualParents);
  if (!Parents.empty() || !VParents.empty()) {
    if (Parents.empty())
      writeLine("Inherits from " + VParents, OS);
    else if (VParents.empty())
      writeLine("Inherits from " + Parents, OS);
    else
      writeLine("Inherits from " + Parents + ", " + VParents, OS);
    writeNewLine(OS);
  }

  if (!I.Members.empty()) {
    writeHeader("Members", 2, OS);
    for (const auto Member : I.Members) {
      std::string Access = getAccess(Member.Access);
      if (Access != "")
        writeLine(Access + " " + Member.Type.Name + " " + Member.Name, OS);
      else
        writeLine(Member.Type.Name + " " + Member.Name, OS);
    }
    writeNewLine(OS);
  }

  if (!I.ChildRecords.empty()) {
    writeHeader("Records", 2, OS);
    for (const auto &R : I.ChildRecords)
      writeLine(R.Name, OS);
    writeNewLine(OS);
  }
  if (!I.ChildFunctions.empty()) {
    writeHeader("Functions", 2, OS);
    for (const auto &F : I.ChildFunctions)
      genMarkdown(F, OS);
    writeNewLine(OS);
  }
  if (!I.ChildEnums.empty()) {
    writeHeader("Enums", 2, OS);
    for (const auto &E : I.ChildEnums)
      genMarkdown(E, OS);
    writeNewLine(OS);
  }
}

/// Generator for Markdown documentation.
class MDGenerator : public Generator {
public:
  static const char *Format;

  llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
};

const char *MDGenerator::Format = "md";

llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
  switch (I->IT) {
  case InfoType::IT_namespace:
    genMarkdown(*static_cast<clang::doc::NamespaceInfo *>(I), OS);
    break;
  case InfoType::IT_record:
    genMarkdown(*static_cast<clang::doc::RecordInfo *>(I), OS);
    break;
  case InfoType::IT_enum:
    genMarkdown(*static_cast<clang::doc::EnumInfo *>(I), OS);
    break;
  case InfoType::IT_function:
    genMarkdown(*static_cast<clang::doc::FunctionInfo *>(I), OS);
    break;
  case InfoType::IT_default:
    return llvm::make_error<llvm::StringError>("Unexpected info type.\n",
                                               llvm::inconvertibleErrorCode());
  }
  return llvm::Error::success();
}

static GeneratorRegistry::Add<MDGenerator> MD(MDGenerator::Format,
                                              "Generator for MD output.");

// This anchor is used to force the linker to link in the generated object file
// and thus register the generator.
volatile int MDGeneratorAnchorSource = 0;

} // namespace doc
} // namespace clang
