/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\
|*                                                                            *|
|*                     The LLVM Compiler Infrastructure                       *|
|*                                                                            *|
|* This file is distributed under the University of Illinois Open Source      *|
|* License. See LICENSE.TXT for details.                                      *|
|*                                                                            *|
|*===----------------------------------------------------------------------===*|
|*                                                                            *|
|* Implements the diagnostic functions of the Clang C interface.              *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/
#include "CIndexDiagnostic.h"
#include "CIndexer.h"
#include "CXTranslationUnit.h"
#include "CXSourceLocation.h"
#include "CXString.h"

#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/DiagnosticRenderer.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace clang::cxloc;
using namespace clang::cxdiag;
using namespace llvm;

CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {}

void
CXDiagnosticSetImpl::appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D) {
  Diagnostics.push_back(std::move(D));
}

CXDiagnosticImpl::~CXDiagnosticImpl() {}

namespace {
class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
  std::string Message;
  CXSourceLocation Loc;
public:
  CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
    : CXDiagnosticImpl(CustomNoteDiagnosticKind),
      Message(Msg), Loc(L) {}

  ~CXDiagnosticCustomNoteImpl() override {}

  CXDiagnosticSeverity getSeverity() const override {
    return CXDiagnostic_Note;
  }

  CXSourceLocation getLocation() const override {
    return Loc;
  }

  CXString getSpelling() const override {
    return cxstring::createRef(Message.c_str());
  }

  CXString getDiagnosticOption(CXString *Disable) const override {
    if (Disable)
      *Disable = cxstring::createEmpty();
    return cxstring::createEmpty();
  }

  unsigned getCategory() const override { return 0; }
  CXString getCategoryText() const override { return cxstring::createEmpty(); }

  unsigned getNumRanges() const override { return 0; }
  CXSourceRange getRange(unsigned Range) const override {
    return clang_getNullRange();
  }
  unsigned getNumFixIts() const override { return 0; }
  CXString getFixIt(unsigned FixIt,
                    CXSourceRange *ReplacementRange) const override {
    if (ReplacementRange)
      *ReplacementRange = clang_getNullRange();
    return cxstring::createEmpty();
  }
};    
    
class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
public:  
  CXDiagnosticRenderer(const LangOptions &LangOpts,
                       DiagnosticOptions *DiagOpts,
                       CXDiagnosticSetImpl *mainSet)
  : DiagnosticNoteRenderer(LangOpts, DiagOpts),
    CurrentSet(mainSet), MainSet(mainSet) {}

  ~CXDiagnosticRenderer() override {}

  void beginDiagnostic(DiagOrStoredDiag D,
                       DiagnosticsEngine::Level Level) override {

    const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
    if (!SD)
      return;
    
    if (Level != DiagnosticsEngine::Note)
      CurrentSet = MainSet;

    auto Owner = llvm::make_unique<CXStoredDiagnostic>(*SD, LangOpts);
    CXStoredDiagnostic &CD = *Owner;
    CurrentSet->appendDiagnostic(std::move(Owner));

    if (Level != DiagnosticsEngine::Note)
      CurrentSet = &CD.getChildDiagnostics();
  }

  void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
                             DiagnosticsEngine::Level Level,
                             StringRef Message,
                             ArrayRef<CharSourceRange> Ranges,
                             const SourceManager *SM,
                             DiagOrStoredDiag D) override {
    if (!D.isNull())
      return;
    
    CXSourceLocation L;
    if (SM)
      L = translateSourceLocation(*SM, LangOpts, Loc);
    else
      L = clang_getNullLocation();
    CurrentSet->appendDiagnostic(
        llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
  }

  void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
                         DiagnosticsEngine::Level Level,
                         ArrayRef<CharSourceRange> Ranges,
                         const SourceManager &SM) override {}

  void emitCodeContext(SourceLocation Loc,
                       DiagnosticsEngine::Level Level,
                       SmallVectorImpl<CharSourceRange>& Ranges,
                       ArrayRef<FixItHint> Hints,
                       const SourceManager &SM) override {}

  void emitNote(SourceLocation Loc, StringRef Message,
                const SourceManager *SM) override {
    CXSourceLocation L;
    if (SM)
      L = translateSourceLocation(*SM, LangOpts, Loc);
    else
      L = clang_getNullLocation();
    CurrentSet->appendDiagnostic(
        llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
  }

  CXDiagnosticSetImpl *CurrentSet;
  CXDiagnosticSetImpl *MainSet;
};  
}

CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
                                             bool checkIfChanged) {
  ASTUnit *AU = cxtu::getASTUnit(TU);

  if (TU->Diagnostics && checkIfChanged) {
    // In normal use, ASTUnit's diagnostics should not change unless we reparse.
    // Currently they can only change by using the internal testing flag
    // '-error-on-deserialized-decl' which will error during deserialization of
    // a declaration. What will happen is:
    //
    //  -c-index-test gets a CXTranslationUnit
    //  -checks the diagnostics, the diagnostics set is lazily created,
    //     no errors are reported
    //  -later does an operation, like annotation of tokens, that triggers
    //     -error-on-deserialized-decl, that will emit a diagnostic error,
    //     that ASTUnit will catch and add to its stored diagnostics vector.
    //  -c-index-test wants to check whether an error occurred after performing
    //     the operation but can only query the lazily created set.
    //
    // We check here if a new diagnostic was appended since the last time the
    // diagnostic set was created, in which case we reset it.

    CXDiagnosticSetImpl *
      Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
    if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
      // Diagnostics in the ASTUnit were updated, reset the associated
      // diagnostics.
      delete Set;
      TU->Diagnostics = nullptr;
    }
  }

  if (!TU->Diagnostics) {
    CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
    TU->Diagnostics = Set;
    IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
    CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
                                  &*DOpts, Set);
    
    for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
         ei = AU->stored_diag_end(); it != ei; ++it) {
      Renderer.emitStoredDiagnostic(*it);
    }
  }
  return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
}

//-----------------------------------------------------------------------------
// C Interface Routines
//-----------------------------------------------------------------------------
extern "C" {

unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
  if (cxtu::isNotUsableTU(Unit)) {
    LOG_BAD_TU(Unit);
    return 0;
  }
  if (!cxtu::getASTUnit(Unit))
    return 0;
  return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
}

CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
  if (cxtu::isNotUsableTU(Unit)) {
    LOG_BAD_TU(Unit);
    return nullptr;
  }

  CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
  if (!D)
    return nullptr;

  CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
  if (Index >= Diags->getNumDiagnostics())
    return nullptr;

  return Diags->getDiagnostic(Index);
}

CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
  if (cxtu::isNotUsableTU(Unit)) {
    LOG_BAD_TU(Unit);
    return nullptr;
  }
  if (!cxtu::getASTUnit(Unit))
    return nullptr;
  return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
}

void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
  // No-op.  Kept as a legacy API.  CXDiagnostics are now managed
  // by the enclosing CXDiagnosticSet.
}

CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
  if (!Diagnostic)
    return cxstring::createEmpty();

  CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);

  SmallString<256> Str;
  llvm::raw_svector_ostream Out(Str);
  
  if (Options & CXDiagnostic_DisplaySourceLocation) {
    // Print source location (file:line), along with optional column
    // and source ranges.
    CXFile File;
    unsigned Line, Column;
    clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
                              &File, &Line, &Column, nullptr);
    if (File) {
      CXString FName = clang_getFileName(File);
      Out << clang_getCString(FName) << ":" << Line << ":";
      clang_disposeString(FName);
      if (Options & CXDiagnostic_DisplayColumn)
        Out << Column << ":";

      if (Options & CXDiagnostic_DisplaySourceRanges) {
        unsigned N = clang_getDiagnosticNumRanges(Diagnostic);
        bool PrintedRange = false;
        for (unsigned I = 0; I != N; ++I) {
          CXFile StartFile, EndFile;
          CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I);
          
          unsigned StartLine, StartColumn, EndLine, EndColumn;
          clang_getSpellingLocation(clang_getRangeStart(Range),
                                    &StartFile, &StartLine, &StartColumn,
                                    nullptr);
          clang_getSpellingLocation(clang_getRangeEnd(Range),
                                    &EndFile, &EndLine, &EndColumn, nullptr);

          if (StartFile != EndFile || StartFile != File)
            continue;
          
          Out << "{" << StartLine << ":" << StartColumn << "-"
              << EndLine << ":" << EndColumn << "}";
          PrintedRange = true;
        }
        if (PrintedRange)
          Out << ":";
      }
      
      Out << " ";
    }
  }

  /* Print warning/error/etc. */
  switch (Severity) {
  case CXDiagnostic_Ignored: llvm_unreachable("impossible");
  case CXDiagnostic_Note: Out << "note: "; break;
  case CXDiagnostic_Warning: Out << "warning: "; break;
  case CXDiagnostic_Error: Out << "error: "; break;
  case CXDiagnostic_Fatal: Out << "fatal error: "; break;
  }

  CXString Text = clang_getDiagnosticSpelling(Diagnostic);
  if (clang_getCString(Text))
    Out << clang_getCString(Text);
  else
    Out << "<no diagnostic text>";
  clang_disposeString(Text);
  
  if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
                 CXDiagnostic_DisplayCategoryName)) {
    bool NeedBracket = true;
    bool NeedComma = false;

    if (Options & CXDiagnostic_DisplayOption) {
      CXString OptionName = clang_getDiagnosticOption(Diagnostic, nullptr);
      if (const char *OptionText = clang_getCString(OptionName)) {
        if (OptionText[0]) {
          Out << " [" << OptionText;
          NeedBracket = false;
          NeedComma = true;
        }
      }
      clang_disposeString(OptionName);
    }
    
    if (Options & (CXDiagnostic_DisplayCategoryId | 
                   CXDiagnostic_DisplayCategoryName)) {
      if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
        if (Options & CXDiagnostic_DisplayCategoryId) {
          if (NeedBracket)
            Out << " [";
          if (NeedComma)
            Out << ", ";
          Out << CategoryID;
          NeedBracket = false;
          NeedComma = true;
        }
        
        if (Options & CXDiagnostic_DisplayCategoryName) {
          CXString CategoryName = clang_getDiagnosticCategoryText(Diagnostic);
          if (NeedBracket)
            Out << " [";
          if (NeedComma)
            Out << ", ";
          Out << clang_getCString(CategoryName);
          NeedBracket = false;
          NeedComma = true;
          clang_disposeString(CategoryName);
        }
      }
    }

    (void) NeedComma; // Silence dead store warning.
    if (!NeedBracket)
      Out << "]";
  }
  
  return cxstring::createDup(Out.str());
}

unsigned clang_defaultDiagnosticDisplayOptions() {
  return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
         CXDiagnostic_DisplayOption;
}

enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
    return D->getSeverity();
  return CXDiagnostic_Ignored;
}

CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
    return D->getLocation();
  return clang_getNullLocation();
}

CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
    return D->getSpelling();
  return cxstring::createEmpty();
}

CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
  if (Disable)
    *Disable = cxstring::createEmpty();

  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
    return D->getDiagnosticOption(Disable);

  return cxstring::createEmpty();
}

unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
    return D->getCategory();
  return 0;
}
  
CXString clang_getDiagnosticCategoryName(unsigned Category) {
  // Kept for backward compatibility.
  return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
}
  
CXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
    return D->getCategoryText();
  return cxstring::createEmpty();
}
  
unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
    return D->getNumRanges();
  return 0;
}

CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
  CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);  
  if (!D || Range >= D->getNumRanges())
    return clang_getNullRange();
  return D->getRange(Range);
}

unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
    return D->getNumFixIts();
  return 0;
}

CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
                                  CXSourceRange *ReplacementRange) {
  CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
  if (!D || FixIt >= D->getNumFixIts()) {
    if (ReplacementRange)
      *ReplacementRange = clang_getNullRange();
    return cxstring::createEmpty();
  }
  return D->getFixIt(FixIt, ReplacementRange);
}

void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl *>(Diags)) {
    if (D->isExternallyManaged())
      delete D;
  }
}
  
CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
                                      unsigned Index) {
  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
    if (Index < D->getNumDiagnostics())
      return D->getDiagnostic(Index);
  return nullptr;
}
  
CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
  if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
    CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
    return ChildDiags.empty() ? nullptr : (CXDiagnosticSet) &ChildDiags;
  }
  return nullptr;
}

unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
    return D->getNumDiagnostics();
  return 0;
}

} // end extern "C"
