/*
 Copyright 2019 Alain Dargelas

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/*
 * File:   ErrorContainer.cpp
 * Author: alain
 *
 * Created on March 5, 2017, 11:12 PM
 */

#include "ErrorContainer.h"
#include <mutex>
#include <iostream>
#include <fstream>
#include "CommandLine/CommandLineParser.hpp"
#include "Waiver.h"

#include "antlr4-runtime.h"
using namespace antlr4;

#include "API/PythonAPI.h"

using namespace SURELOG;

ErrorContainer::ErrorContainer(SymbolTable* symbolTable)
    : m_clp(NULL),
      m_reportedFatalErrorLogFile(false),
      m_symbolTable(symbolTable),
      m_interpState(NULL) {
  m_interpState = PythonAPI::getMainInterp();
  /* Do nothing here */
}

void ErrorContainer::init() {
  if (ErrorDefinition::init()) {
    const std::string& logFileName =
        m_clp->getSymbolTable()->getSymbol(m_clp->getLogFileId());
    std::ofstream ofs;
    ofs.open(logFileName, std::fstream::out);
    if (!ofs.good()) {
      std::cerr << "[FATAL:LG0001] Cannot create log file \"" << logFileName
                << "\"" << std::endl;
      return;
    }
    ofs.close();
  }
}

ErrorContainer::ErrorContainer(const ErrorContainer& orig) {}

ErrorContainer::~ErrorContainer() {}

Error& ErrorContainer::addError(Error& error, bool showDuplicates,
                                bool reentrantPython) {
  std::tuple<std::string, bool, bool> textStatus =
      createErrorMessage(error, reentrantPython);
  if (std::get<2>(textStatus))  // filter Message
    return error;

  std::multimap<ErrorDefinition::ErrorType, Waiver::WaiverData>& waivers =
      Waiver::getWaivers();
  std::pair<
      std::multimap<ErrorDefinition::ErrorType, Waiver::WaiverData>::iterator,
      std::multimap<ErrorDefinition::ErrorType, Waiver::WaiverData>::iterator>
      ret = waivers.equal_range(error.m_errorId);
  for (std::multimap<ErrorDefinition::ErrorType, Waiver::WaiverData>::iterator
           it = ret.first;
       it != ret.second; ++it) {
    if ((((*it).second.m_fileName == "") ||
         (m_symbolTable->getSymbol(error.m_locations[0].m_fileId) ==
          (*it).second.m_fileName)) &&
        (((*it).second.m_line == 0) ||
         (error.m_locations[0].m_line == (*it).second.m_line)) &&
        (((*it).second.m_objectId == "") ||
         (m_symbolTable->getSymbol(error.m_locations[0].m_object) ==
          (*it).second.m_objectId))) {
      error.m_waived = true;
      break;
    }
  }

  if (showDuplicates) {
    m_errors.push_back(error);
  } else {
    if (m_errorSet.find(std::get<0>(textStatus)) == m_errorSet.end()) {
      m_errors.push_back(error);
      m_errorSet.insert(std::get<0>(textStatus));
    }
  }
  return m_errors[m_errors.size() - 1];
}

void ErrorContainer::appendErrors(ErrorContainer& rhs) {
  for (unsigned int i = 0; i < rhs.m_errors.size(); i++) {
    Error err = rhs.m_errors[i];
    // Translate IDs to master symbol table
    for (unsigned int locItr = 0; locItr < err.m_locations.size(); locItr++) {
      Location& loc = err.m_locations[locItr];
      if (loc.m_fileId)
        loc.m_fileId = m_symbolTable->registerSymbol(
            rhs.m_symbolTable->getSymbol(loc.m_fileId));
      if (loc.m_object) {
        loc.m_object = m_symbolTable->registerSymbol(
            rhs.m_symbolTable->getSymbol(loc.m_object));
      }
    }
    if (!err.m_reported) addError(err);
  }
}

std::tuple<std::string, bool, bool> ErrorContainer::createErrorMessage(
    Error& msg, bool reentrantPython) {
  const std::map<ErrorDefinition::ErrorType, ErrorDefinition::ErrorInfo>&
      infoMap = ErrorDefinition::getErrorInfoMap();
  std::string tmp;
  bool reportFatalError = false;
  bool filterMessage = false;
  if ((!msg.m_reported) && (!msg.m_waived)) {
    ErrorDefinition::ErrorType type = msg.m_errorId;
    std::map<ErrorDefinition::ErrorType,
             ErrorDefinition::ErrorInfo>::const_iterator itr =
        infoMap.find(type);
    if (itr != infoMap.end()) {
      ErrorDefinition::ErrorInfo info = (*itr).second;
      std::string severity;
      switch (info.m_severity) {
        case ErrorDefinition::FATAL:
          severity = "FATAL";
          reportFatalError = true;
          break;
        case ErrorDefinition::ERROR:
          severity = "ERROR";
          break;
        case ErrorDefinition::WARNING:
          severity = "WARNI";
          if (m_clp->filterWarning()) filterMessage = true;
          break;
        case ErrorDefinition::INFO:
          severity = "INFO ";
          if (m_clp->filterInfo() &&
              (type != ErrorDefinition::PP_PROCESSING_SOURCE_FILE))
            filterMessage = true;
          break;
        case ErrorDefinition::NOTE:
          severity = "NOTE ";
          if (m_clp->filterNote()) filterMessage = true;
          break;
      }
      std::string category = ErrorDefinition::getCategoryName(info.m_category);

      Location& loc = msg.m_locations[0];
      /* Object */
      std::string text = info.m_errorText;
      const std::string& objectName = m_symbolTable->getSymbol(loc.m_object);
      if (objectName != m_symbolTable->getBadSymbol()) {
        size_t objectOffset = text.find("%s");
        if (objectOffset != std::string::npos) {
          text = text.replace(objectOffset, 2, objectName);
        }
      }

      /* Location */
      std::string location;
      if (loc.m_fileId == 0) {
      } else {
        const std::string& fileName = m_symbolTable->getSymbol(loc.m_fileId);
        location = fileName;
        if (loc.m_line > 0) {
          location += ":" + std::to_string(loc.m_line);
          // Emacs does not like column
          // if (loc.m_column > 0)
          //  location += ":" + std::to_string (loc.m_column);
        }
        location += " ";
      }

      /* Extra locations */
      unsigned int nbExtraLoc = msg.m_locations.size();
      for (unsigned int i = 1; i < nbExtraLoc; i++) {
        Location& extraLoc = msg.m_locations[i];
        if (extraLoc.m_fileId) {
          std::string extraLocation;
          const std::string& fileName =
              m_symbolTable->getSymbol(extraLoc.m_fileId);
          extraLocation = fileName;
          if (extraLoc.m_line > 0) {
            extraLocation += ":" + std::to_string(extraLoc.m_line);
            // Emacs does not like column
            // if (extraLoc.m_column > 0)
            //  extraLocation += ":" + std::to_string (extraLoc.m_column);
          }
          size_t objectOffset = text.find("%exloc");
          if (objectOffset != std::string::npos) {
            text = text.replace(objectOffset, 6, extraLocation);
          } else if (info.m_extraText != "") {
            text += ",\n               " + info.m_extraText;
            // text += ",\n" + info.m_extraText;
            size_t objectOffset = text.find("%exloc");
            if (objectOffset != std::string::npos) {
              text = text.replace(objectOffset, 6, extraLocation);
            }
          }
        } else {
          if (info.m_extraText != "") {
            if ((nbExtraLoc == 2) && (extraLoc.m_fileId == 0))
              text += ",\n" + info.m_extraText;
            else
              text += ",\n               " + info.m_extraText;
          }
        }
        if (extraLoc.m_object) {
          const std::string& objString =
              m_symbolTable->getSymbol(extraLoc.m_object);
          size_t objectOffset = text.find("%exobj");
          if (objectOffset != std::string::npos) {
            text = text.replace(objectOffset, 6, objString);
          }
        }
      }
      text += ".";
      std::string padding;
      if (msg.m_errorId < 10)
        padding = "000";
      else if (msg.m_errorId < 100)
        padding = "00";
      else if (msg.m_errorId < 1000)
        padding = "0";
      if ((reentrantPython == false) || (!m_clp->pythonAllowed())) {
        tmp = "[" + severity + ":" + category + padding +
              std::to_string(msg.m_errorId) + "] " + location + text + "\n\n";
      } else {
        std::vector<std::string> args;
        args.push_back(severity);
        args.push_back(category);
        args.push_back(padding + std::to_string(msg.m_errorId));
        args.push_back(location);
        args.push_back(text);
        tmp = PythonAPI::evalScript("__main__", "SLformatMsg", args,
                                    m_interpState);
      }
    }
  }
  return std::make_tuple(tmp, reportFatalError, filterMessage);
}

bool ErrorContainer::hasFatalErrors() {
  const std::map<ErrorDefinition::ErrorType, ErrorDefinition::ErrorInfo>&
      infoMap = ErrorDefinition::getErrorInfoMap();
  bool reportFatalError = false;
  for (unsigned int i = 0; i < m_errors.size(); i++) {
    Error& msg = m_errors[i];
    ErrorDefinition::ErrorType type = msg.m_errorId;
    std::map<ErrorDefinition::ErrorType,
             ErrorDefinition::ErrorInfo>::const_iterator itr =
        infoMap.find(type);
    if (itr != infoMap.end()) {
      ErrorDefinition::ErrorInfo info = (*itr).second;
      std::string severity;
      switch (info.m_severity) {
        case ErrorDefinition::FATAL:
          reportFatalError = true;
          break;
        default:
          break;
      }
    }
  }
  return reportFatalError;
}

std::pair<std::string, bool> ErrorContainer::createReport_() {
  std::string report;
  bool reportFatalError = false;
  for (unsigned int i = 0; i < m_errors.size(); i++) {
    Error& msg = m_errors[i];
    std::tuple<std::string, bool, bool> textStatus = createErrorMessage(msg);
    if (std::get<1>(textStatus)) reportFatalError = true;
    if (std::get<2>(textStatus))  // Filtered
      continue;
    report += std::get<0>(textStatus);
    msg.m_reported = true;
  }
  return std::make_pair(report, reportFatalError);
}

std::pair<std::string, bool> ErrorContainer::createReport_(Error& error) {
  std::string report;
  bool reportFatalError = false;
  Error& msg = error;
  std::tuple<std::string, bool, bool> textStatus = createErrorMessage(msg);
  if (std::get<1>(textStatus)) reportFatalError = true;
  if (!std::get<2>(textStatus))  // Filtered
    report += std::get<0>(textStatus);
  msg.m_reported = true;
  return std::make_pair(report, reportFatalError);
}

bool ErrorContainer::printStats(ErrorContainer::Stats stats, bool muteStdout) {
  std::string report;
  report += "[  FATAL] : " + std::to_string(stats.nbFatal) + "\n";
  report += "[  ERROR] : " + std::to_string(stats.nbError) + "\n";
  report += "[WARNING] : " + std::to_string(stats.nbWarning) + "\n";
  // BOGUS NUMBER IN CACHED MODE  report += "[   INFO] : " +
  // std::to_string(stats.nbInfo) + "\n";
  report += "[   NOTE] : " + std::to_string(stats.nbNote) + "\n";
  if (!muteStdout) {
    std::cout << report << std::flush;
  }
  bool successLogFile = printToLogFile(report);
  return (successLogFile && (!stats.nbFatal));
}

ErrorContainer::Stats ErrorContainer::getErrorStats() {
  const std::map<ErrorDefinition::ErrorType, ErrorDefinition::ErrorInfo>&
      infoMap = ErrorDefinition::getErrorInfoMap();
  ErrorContainer::Stats stats;
  for (auto msg : m_errors) {
    if (!msg.m_waived) {
      ErrorDefinition::ErrorType type = msg.m_errorId;
      std::map<ErrorDefinition::ErrorType,
               ErrorDefinition::ErrorInfo>::const_iterator itr =
          infoMap.find(type);
      if (itr != infoMap.end()) {
        ErrorDefinition::ErrorInfo info = (*itr).second;
        switch (info.m_severity) {
          case ErrorDefinition::FATAL:
            stats.nbFatal++;
            break;
          case ErrorDefinition::ERROR:
            stats.nbError++;
            break;
          case ErrorDefinition::WARNING:
            stats.nbWarning++;
            break;
          case ErrorDefinition::INFO:
            stats.nbInfo++;
            break;
          case ErrorDefinition::NOTE:
            stats.nbNote++;
            break;
        }
      }
    }
  }
  return stats;
}

static std::mutex m;
bool ErrorContainer::printToLogFile(std::string report) {
  m.lock();
  const std::string& logFileName =
      m_clp->getSymbolTable()->getSymbol(m_clp->getLogFileId());
  std::ofstream ofs;
  ofs.open(logFileName, std::fstream::app);
  if (!ofs.good()) {
    if (!m_reportedFatalErrorLogFile) {
      std::cerr << "[FATAL:LG0002] Cannot open log file \"" << logFileName
                << "\" in append mode" << std::endl;
      m_reportedFatalErrorLogFile = true;
    }
    m.unlock();
    return false;
  } else {
    ofs << report << std::flush;
    ofs.close();
  }
  m.unlock();
  return true;
}

bool ErrorContainer::printMessage(Error& error, bool muteStdout) {
  if (error.m_reported) return false;
  std::pair<std::string, bool> report = createReport_(error);

  if (!muteStdout) {
    std::cout << report.first << std::flush;
  }
  bool successLogFile = printToLogFile(report.first);
  error.m_reported = true;
  return (successLogFile && (!report.second));
}

bool ErrorContainer::printMessages(bool muteStdout) {
  std::pair<std::string, bool> report = createReport_();

  if (!muteStdout) {
    std::cout << report.first << std::flush;
  }
  bool successLogFile = printToLogFile(report.first);
  return (successLogFile && (!report.second));
}
