//===--- HTMLDiagnostics.cpp - HTML Diagnostics for Paths ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the HTMLDiagnostics object.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/PathDiagnosticClients.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/Rewrite/Rewriter.h"
#include "clang/Rewrite/HTMLRewrite.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Path.h"
#include <fstream>
using namespace clang;

//===----------------------------------------------------------------------===//
// Boilerplate.
//===----------------------------------------------------------------------===//

namespace {

class VISIBILITY_HIDDEN HTMLDiagnostics : public PathDiagnosticClient {
  llvm::sys::Path Directory, FilePrefix;
  bool createdDir, noDir;
  Preprocessor* PP;
  std::vector<const PathDiagnostic*> BatchedDiags;
  llvm::SmallVectorImpl<std::string> *FilesMade;  
public:
  HTMLDiagnostics(const std::string& prefix, Preprocessor* pp,
                  llvm::SmallVectorImpl<std::string> *filesMade = 0);

  virtual ~HTMLDiagnostics();
  
  virtual void SetPreprocessor(Preprocessor *pp) { PP = pp; }
  
  virtual void HandlePathDiagnostic(const PathDiagnostic* D);
  
  unsigned ProcessMacroPiece(llvm::raw_ostream& os,
                             const PathDiagnosticMacroPiece& P,
                             unsigned num);
    
  void HandlePiece(Rewriter& R, FileID BugFileID,
                   const PathDiagnosticPiece& P, unsigned num, unsigned max);
  
  void HighlightRange(Rewriter& R, FileID BugFileID, SourceRange Range,
                      const char *HighlightStart = "<span class=\"mrange\">",
                      const char *HighlightEnd = "</span>");

  void ReportDiag(const PathDiagnostic& D);
};
  
} // end anonymous namespace

HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix, Preprocessor* pp,
                                 llvm::SmallVectorImpl<std::string>* filesMade)
  : Directory(prefix), FilePrefix(prefix), createdDir(false), noDir(false),
    PP(pp), FilesMade(filesMade) {
  
  // All html files begin with "report" 
  FilePrefix.appendComponent("report");
}

PathDiagnosticClient*
clang::CreateHTMLDiagnosticClient(const std::string& prefix, Preprocessor* PP,
                                  PreprocessorFactory*,
                                  llvm::SmallVectorImpl<std::string>* FilesMade)
{
  return new HTMLDiagnostics(prefix, PP, FilesMade);
}

//===----------------------------------------------------------------------===//
// Factory for HTMLDiagnosticClients
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN HTMLDiagnosticsFactory
  : public PathDiagnosticClientFactory {

  std::string Prefix;
  Preprocessor *PP;
public:
  HTMLDiagnosticsFactory(const std::string& prefix, Preprocessor* pp)
    : Prefix(prefix), PP(pp) {}

  virtual ~HTMLDiagnosticsFactory() {}
    
  const char *getName() const { return "HTMLDiagnostics"; }
    
  PathDiagnosticClient*
  createPathDiagnosticClient(llvm::SmallVectorImpl<std::string> *FilesMade) {

  return new HTMLDiagnostics(Prefix, PP, FilesMade);
  }
};
} // end anonymous namespace

PathDiagnosticClientFactory*
clang::CreateHTMLDiagnosticClientFactory(const std::string& prefix,
                                         Preprocessor* PP,
                                         PreprocessorFactory*) {
  return new HTMLDiagnosticsFactory(prefix, PP);
}

//===----------------------------------------------------------------------===//
// Report processing.
//===----------------------------------------------------------------------===//

void HTMLDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
  if (!D)
    return;
  
  if (D->empty()) {
    delete D;
    return;
  }
  
  const_cast<PathDiagnostic*>(D)->flattenLocations();
  BatchedDiags.push_back(D);
}

HTMLDiagnostics::~HTMLDiagnostics() {
  while (!BatchedDiags.empty()) {
    const PathDiagnostic* D = BatchedDiags.back();
    BatchedDiags.pop_back();
    ReportDiag(*D);
    delete D;
  }  
}

void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) {
  // Create the HTML directory if it is missing.
  if (!createdDir) {
    createdDir = true;
    std::string ErrorMsg;
    Directory.createDirectoryOnDisk(true, &ErrorMsg);
  
    if (!Directory.isDirectory()) {
      llvm::cerr << "warning: could not create directory '"
                 << Directory.toString() << "'\n"
                 << "reason: " << ErrorMsg << '\n'; 
      
      noDir = true;
      
      return;
    }
  }
  
  if (noDir)
    return;
  
  const SourceManager &SMgr = D.begin()->getLocation().getManager();
  FileID FID;
  
  // Verify that the entire path is from the same FileID.
  for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
    FullSourceLoc L = I->getLocation().asLocation().getInstantiationLoc();
    
    if (FID.isInvalid()) {
      FID = SMgr.getFileID(L);
    } else if (SMgr.getFileID(L) != FID)
      return; // FIXME: Emit a warning?
    
    // Check the source ranges.
    for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
                                             RE=I->ranges_end(); RI!=RE; ++RI) {
      
      SourceLocation L = SMgr.getInstantiationLoc(RI->getBegin());

      if (!L.isFileID() || SMgr.getFileID(L) != FID)
        return; // FIXME: Emit a warning?
      
      L = SMgr.getInstantiationLoc(RI->getEnd());
      
      if (!L.isFileID() || SMgr.getFileID(L) != FID)
        return; // FIXME: Emit a warning?      
    }
  }
  
  if (FID.isInvalid())
    return; // FIXME: Emit a warning?
  
  // Create a new rewriter to generate HTML.
  Rewriter R(const_cast<SourceManager&>(SMgr), PP->getLangOptions());
  
  // Process the path.  
  unsigned n = D.size();
  unsigned max = n;
  
  for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
        I!=E; ++I, --n)
    HandlePiece(R, FID, *I, n, max);
  
  // Add line numbers, header, footer, etc.
  
  // unsigned FID = R.getSourceMgr().getMainFileID();
  html::EscapeText(R, FID);
  html::AddLineNumbers(R, FID);
  
  // If we have a preprocessor, relex the file and syntax highlight.
  // We might not have a preprocessor if we come from a deserialized AST file,
  // for example.
  
  if (PP) html::SyntaxHighlight(R, FID, *PP);

  // FIXME: We eventually want to use PPF to create a fresh Preprocessor,
  //  once we have worked out the bugs.
  //
  // if (PPF) html::HighlightMacros(R, FID, *PPF);
  //
  if (PP) html::HighlightMacros(R, FID, *PP);
  
  // Get the full directory name of the analyzed file.

  const FileEntry* Entry = SMgr.getFileEntryForID(FID);
  
  // This is a cludge; basically we want to append either the full
  // working directory if we have no directory information.  This is
  // a work in progress.

  std::string DirName = "";
  
  if (!llvm::sys::Path(Entry->getName()).isAbsolute()) {
    llvm::sys::Path P = llvm::sys::Path::GetCurrentDirectory();
    DirName = P.toString() + "/";
  }
    
  // Add the name of the file as an <h1> tag.  
  
  {
    std::string s;
    llvm::raw_string_ostream os(s);
    
    os << "<!-- REPORTHEADER -->\n"
      << "<h3>Bug Summary</h3>\n<table class=\"simpletable\">\n"
          "<tr><td class=\"rowname\">File:</td><td>"
      << html::EscapeText(DirName)
      << html::EscapeText(Entry->getName())
      << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
         "<a href=\"#EndPath\">line "      
      << (*D.rbegin()).getLocation().asLocation().getInstantiationLineNumber()
      << ", column "
      << (*D.rbegin()).getLocation().asLocation().getInstantiationColumnNumber()
      << "</a></td></tr>\n"
         "<tr><td class=\"rowname\">Description:</td><td>"
      << D.getDescription() << "</td></tr>\n";
    
    // Output any other meta data.
    
    for (PathDiagnostic::meta_iterator I=D.meta_begin(), E=D.meta_end();
         I!=E; ++I) {
      os << "<tr><td></td><td>" << html::EscapeText(*I) << "</td></tr>\n";
    }
    
    os << "</table>\n<!-- REPORTSUMMARYEXTRA -->\n"
          "<h3>Annotated Source Code</h3>\n";    
    
    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
  }
  
  // Embed meta-data tags.
  
  const std::string& BugDesc = D.getDescription();
  
  if (!BugDesc.empty()) {
    std::string s;
    llvm::raw_string_ostream os(s);
    os << "\n<!-- BUGDESC " << BugDesc << " -->\n";
    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
  }
  
  const std::string& BugType = D.getBugType();
  if (!BugType.empty()) {
    std::string s;
    llvm::raw_string_ostream os(s);
    os << "\n<!-- BUGTYPE " << BugType << " -->\n";
    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
  }
  
  const std::string& BugCategory = D.getCategory();
  
  if (!BugCategory.empty()) {
    std::string s;
    llvm::raw_string_ostream os(s);
    os << "\n<!-- BUGCATEGORY " << BugCategory << " -->\n";
    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
  }
  
  {
    std::string s;
    llvm::raw_string_ostream os(s);
    os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
  }
  
  {
    std::string s;
    llvm::raw_string_ostream os(s);
    os << "\n<!-- BUGLINE "
       << D.back()->getLocation().asLocation().getInstantiationLineNumber()
       << " -->\n";
    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
  }
  
  {
    std::string s;
    llvm::raw_string_ostream os(s);
    os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
    R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str());
  }

  // Add CSS, header, and footer.
  
  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
  
  // Get the rewrite buffer.
  const RewriteBuffer *Buf = R.getRewriteBufferFor(FID);
  
  if (!Buf) {
    llvm::cerr << "warning: no diagnostics generated for main file.\n";
    return;
  }

  // Create the stream to write out the HTML.
  std::ofstream os;
  
  {
    // Create a path for the target HTML file.
    llvm::sys::Path F(FilePrefix);
    F.makeUnique(false, NULL);
  
    // Rename the file with an HTML extension.
    llvm::sys::Path H(F);
    H.appendSuffix("html");
    F.renamePathOnDisk(H, NULL);
    
    os.open(H.toString().c_str());
    
    if (!os) {
      llvm::cerr << "warning: could not create file '" << F.toString() << "'\n";
      return;
    }

    if (FilesMade)
      FilesMade->push_back(H.getLast());
  }
  
  // Emit the HTML to disk.
  for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I)
      os << *I;  
}

void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
                                  const PathDiagnosticPiece& P,
                                  unsigned num, unsigned max) {
  
  // For now, just draw a box above the line in question, and emit the
  // warning.
  FullSourceLoc Pos = P.getLocation().asLocation();
  
  if (!Pos.isValid())
    return;  
  
  SourceManager &SM = R.getSourceMgr();
  assert(&Pos.getManager() == &SM && "SourceManagers are different!");
  std::pair<FileID, unsigned> LPosInfo = SM.getDecomposedInstantiationLoc(Pos);
  
  if (LPosInfo.first != BugFileID)
    return;
  
  const llvm::MemoryBuffer *Buf = SM.getBuffer(LPosInfo.first);
  const char* FileStart = Buf->getBufferStart();  
  
  // Compute the column number.  Rewind from the current position to the start
  // of the line.
  unsigned ColNo = SM.getColumnNumber(LPosInfo.first, LPosInfo.second);
  const char *TokInstantiationPtr =Pos.getInstantiationLoc().getCharacterData();
  const char *LineStart = TokInstantiationPtr-ColNo;

  // Compute LineEnd.
  const char *LineEnd = TokInstantiationPtr;
  const char* FileEnd = Buf->getBufferEnd();
  while (*LineEnd != '\n' && LineEnd != FileEnd)
    ++LineEnd;
  
  // Compute the margin offset by counting tabs and non-tabs.
  unsigned PosNo = 0;  
  for (const char* c = LineStart; c != TokInstantiationPtr; ++c)
    PosNo += *c == '\t' ? 8 : 1;
  
  // Create the html for the message.

  const char *Kind = 0;
  switch (P.getKind()) {
    case PathDiagnosticPiece::Event:  Kind = "Event"; break;
    case PathDiagnosticPiece::ControlFlow: Kind = "Control"; break;
      // Setting Kind to "Control" is intentional.
    case PathDiagnosticPiece::Macro: Kind = "Control"; break;
  }
    
  std::string sbuf;
  llvm::raw_string_ostream os(sbuf);
    
  os << "\n<tr><td class=\"num\"></td><td class=\"line\"><div id=\"";
    
  if (num == max)
    os << "EndPath";
  else
    os << "Path" << num;
    
  os << "\" class=\"msg";
  if (Kind)
    os << " msg" << Kind;  
  os << "\" style=\"margin-left:" << PosNo << "ex";
    
  // Output a maximum size.
  if (!isa<PathDiagnosticMacroPiece>(P)) {
    // Get the string and determining its maximum substring.
    const std::string& Msg = P.getString();
    unsigned max_token = 0;
    unsigned cnt = 0;
    unsigned len = Msg.size();
    
    for (std::string::const_iterator I=Msg.begin(), E=Msg.end(); I!=E; ++I)
      switch (*I) {
        default:
          ++cnt;
          continue;    
        case ' ':
        case '\t':
        case '\n':
          if (cnt > max_token) max_token = cnt;
          cnt = 0;
      }
    
    if (cnt > max_token)
      max_token = cnt;
    
    // Determine the approximate size of the message bubble in em.
    unsigned em;
    const unsigned max_line = 120;
    
    if (max_token >= max_line)
      em = max_token / 2;
    else {
      unsigned characters = max_line;
      unsigned lines = len / max_line;
    
      if (lines > 0) {
        for (; characters > max_token; --characters)
          if (len / characters > lines) {
            ++characters;
            break;
          }
      }
    
      em = characters / 2;
    }
  
    if (em < max_line/2)
      os << "; max-width:" << em << "em";      
  }
  else
    os << "; max-width:100em";
  
  os << "\">";
  
  if (max > 1) {
    os << "<table class=\"msgT\"><tr><td valign=\"top\">";
    os << "<div class=\"PathIndex";
    if (Kind) os << " PathIndex" << Kind;
    os << "\">" << num << "</div>";
    os << "</td><td>";
  }

  if (const PathDiagnosticMacroPiece *MP =
        dyn_cast<PathDiagnosticMacroPiece>(&P)) {        

    os << "Within the expansion of the macro '";
    
    // Get the name of the macro by relexing it.
    {
      FullSourceLoc L = MP->getLocation().asLocation().getInstantiationLoc();
      assert(L.isFileID());
      std::pair<const char*, const char*> BufferInfo = L.getBufferData();
      const char* MacroName = L.getDecomposedLoc().second + BufferInfo.first;
      Lexer rawLexer(L, PP->getLangOptions(), BufferInfo.first,
                     MacroName, BufferInfo.second);
      
      Token TheTok;
      rawLexer.LexFromRawLexer(TheTok);
      for (unsigned i = 0, n = TheTok.getLength(); i < n; ++i)
        os << MacroName[i];
    }
      
    os << "':\n";
    
    if (max > 1)
      os << "</td></tr></table>";

    // Within a macro piece.  Write out each event.
    ProcessMacroPiece(os, *MP, 0);
  }
  else {
    os << html::EscapeText(P.getString());
    
    if (max > 1)
      os << "</td></tr></table>";
  }
  
  os << "</div></td></tr>";

  // Insert the new html.
  unsigned DisplayPos = LineEnd - FileStart;    
  SourceLocation Loc = 
    SM.getLocForStartOfFile(LPosInfo.first).getFileLocWithOffset(DisplayPos);

  R.InsertStrBefore(Loc, os.str());

  // Now highlight the ranges.  
  for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
        I != E; ++I)
    HighlightRange(R, LPosInfo.first, *I);

#if 0
  // If there is a code insertion hint, insert that code.
  // FIXME: This code is disabled because it seems to mangle the HTML
  // output. I'm leaving it here because it's generally the right idea,
  // but needs some help from someone more familiar with the rewriter.
  for (const CodeModificationHint *Hint = P.code_modifications_begin(),
                               *HintEnd = P.code_modifications_end();
       Hint != HintEnd; ++Hint) {
    if (Hint->RemoveRange.isValid()) {
      HighlightRange(R, LPosInfo.first, Hint->RemoveRange,
                     "<span class=\"CodeRemovalHint\">", "</span>");
    }
    if (Hint->InsertionLoc.isValid()) {
      std::string EscapedCode = html::EscapeText(Hint->CodeToInsert, true);
      EscapedCode = "<span class=\"CodeInsertionHint\">" + EscapedCode
        + "</span>";
      R.InsertStrBefore(Hint->InsertionLoc, EscapedCode);
    }
  }
#endif
}

static void EmitAlphaCounter(llvm::raw_ostream& os, unsigned n) {
  llvm::SmallVector<char, 10> buf;

  do {
    unsigned x = n % ('z' - 'a');
    buf.push_back('a' + x);
    n = n / ('z' - 'a');
  } while (n);
  
  assert(!buf.empty());
  
  for (llvm::SmallVectorImpl<char>::reverse_iterator I=buf.rbegin(),
       E=buf.rend(); I!=E; ++I)
    os << *I;
}

unsigned HTMLDiagnostics::ProcessMacroPiece(llvm::raw_ostream& os,
                                            const PathDiagnosticMacroPiece& P,
                                            unsigned num) {
  
  for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
        I!=E; ++I) {
    
    if (const PathDiagnosticMacroPiece *MP =
          dyn_cast<PathDiagnosticMacroPiece>(*I)) {
      num = ProcessMacroPiece(os, *MP, num);
      continue;
    }

    if (PathDiagnosticEventPiece *EP = dyn_cast<PathDiagnosticEventPiece>(*I)) {
      os << "<div class=\"msg msgEvent\" style=\"width:94%; "
            "margin-left:5px\">"
            "<table class=\"msgT\"><tr>"
            "<td valign=\"top\"><div class=\"PathIndex PathIndexEvent\">";
      EmitAlphaCounter(os, num++);
      os << "</div></td><td valign=\"top\">"
         << html::EscapeText(EP->getString())
         << "</td></tr></table></div>\n";
    }
  }
  
  return num;
}

void HTMLDiagnostics::HighlightRange(Rewriter& R, FileID BugFileID,
                                     SourceRange Range,
                                     const char *HighlightStart,
                                     const char *HighlightEnd) {
  SourceManager &SM = R.getSourceMgr();
  const LangOptions &LangOpts = R.getLangOpts();
  
  SourceLocation InstantiationStart = SM.getInstantiationLoc(Range.getBegin());
  unsigned StartLineNo = SM.getInstantiationLineNumber(InstantiationStart);
  
  SourceLocation InstantiationEnd = SM.getInstantiationLoc(Range.getEnd());
  unsigned EndLineNo = SM.getInstantiationLineNumber(InstantiationEnd);
  
  if (EndLineNo < StartLineNo)
    return;
  
  if (SM.getFileID(InstantiationStart) != BugFileID ||
      SM.getFileID(InstantiationEnd) != BugFileID)
    return;
    
  // Compute the column number of the end.
  unsigned EndColNo = SM.getInstantiationColumnNumber(InstantiationEnd);
  unsigned OldEndColNo = EndColNo;

  if (EndColNo) {
    // Add in the length of the token, so that we cover multi-char tokens.
    EndColNo += Lexer::MeasureTokenLength(Range.getEnd(), SM, LangOpts)-1;
  }
  
  // Highlight the range.  Make the span tag the outermost tag for the
  // selected range.
    
  SourceLocation E =
    InstantiationEnd.getFileLocWithOffset(EndColNo - OldEndColNo);
  
  html::HighlightRange(R, InstantiationStart, E, HighlightStart, HighlightEnd);
}
