/*
 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:   Report.cpp
 * Author: alain
 *
 * Created on April 10, 2017, 8:56 PM
 */

#include "../SourceCompile/SymbolTable.h"
#include "ErrorContainer.h"
#include "../CommandLine/CommandLineParser.hpp"
#include "Report.h"
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <iomanip>
#include <regex>
#include <mutex>
using namespace SURELOG;

Report::Report() {}

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

Report::~Report() {}

class Result {
 public:
  std::string m_nbFatal;
  std::string m_nbError;
  std::string m_nbWarning;
  std::string m_nbNote;
  std::string m_nbInfo;
};

bool parseReportFile(std::string logFile, Result& result) {
  bool ret = false;
  std::ifstream ifs(logFile.c_str());
  if (!ifs.bad()) {
    std::string line;
    while (std::getline(ifs, line)) {
      if (ifs.bad()) break;
      if (line.find("[  FATAL] : ") != std::string::npos) {
        result.m_nbFatal = line.substr(12, line.size() - 11);
      }
      if (line.find("[  ERROR] : ") != std::string::npos) {
        result.m_nbError = line.substr(12, line.size() - 11);
      }
      if (line.find("[WARNING] : ") != std::string::npos) {
        result.m_nbWarning = line.substr(12, line.size() - 11);
      }
      if (line.find("[   NOTE] : ") != std::string::npos) {
        result.m_nbNote = line.substr(12, line.size() - 11);
        ret = true;
      }
      if (line.find("[   INFO] : ") != std::string::npos) {
        result.m_nbInfo = line.substr(12, line.size() - 11);
        ret = true;
      }
    }
  }

  ifs.close();
  return ret;
}

std::pair<bool, bool> Report::makeDiffCompUnitReport(CommandLineParser* clp,
                                                     SymbolTable* st) {
  // std::mutex m;
  // m.lock();
  std::string odir = st->getSymbol(clp->getOutputDir());
  std::string alldir = st->getSymbol(clp->getCompileAllDir());
  std::string unitdir = st->getSymbol(clp->getCompileUnitDir());
  std::string log = st->getSymbol(clp->getDefaultLogFileId());
  std::string alllog = odir + alldir + log;
  std::string unitlog = odir + unitdir + log;
  bool readAll = false;
  bool readUnit = false;
  Result readAllResult;
  Result readUnitResult;

  while ((!readAll) || (!readUnit)) {
    usleep(1000);
    if (!readAll) {
      readAll = parseReportFile(alllog, readAllResult);
    }
    if (!readUnit) {
      readUnit = parseReportFile(unitlog, readUnitResult);
    }
  }

  clp->printBanner();

  std::cout << "|-------|------------------|-------------------|" << std::endl;
  std::cout << "|       |  FILE UNIT COMP  |  ALL COMPILATION  |" << std::endl;
  std::cout << "|-------|------------------|-------------------|" << std::endl;
  std::cout << "| FATAL | " << std::setw(9) << readUnitResult.m_nbFatal
            << "        | " << std::setw(9) << readAllResult.m_nbFatal
            << "         |" << std::endl;
  std::cout << "| ERROR | " << std::setw(9) << readUnitResult.m_nbError
            << "        | " << std::setw(9) << readAllResult.m_nbError
            << "         |" << std::endl;
  std::cout << "|WARNING| " << std::setw(9) << readUnitResult.m_nbWarning
            << "        | " << std::setw(9) << readAllResult.m_nbWarning
            << "         |" << std::endl;
  std::cout << "| INFO  | " << std::setw(9) << readUnitResult.m_nbInfo
            << "        | " << std::setw(9) << readAllResult.m_nbInfo
            << "         |" << std::endl;
  std::cout << "| NOTE  | " << std::setw(9) << readUnitResult.m_nbNote
            << "        | " << std::setw(9) << readAllResult.m_nbNote
            << "         |" << std::endl;
  std::cout << "|-------|------------------|-------------------|" << std::endl;
  std::cout << std::endl;
  std::cout << "FILE UNIT LOG: " << unitlog << std::endl;
  std::cout << "ALL FILES LOG: " << alllog << std::endl;

  std::string diffFile = odir + unitdir + "diff.log";

  std::string diffCmd = "diff -r " + odir + unitdir + " " + odir + alldir +
                        " --exclude cache --brief > " + diffFile;

  int retval = system(diffCmd.c_str());

  std::ifstream ifs(diffFile.c_str());
  if (!ifs.bad()) {
    std::cout << "\nDIFFS:" << std::endl;
    std::string line;
    while (std::getline(ifs, line)) {
      if (line.find("diff.log") != std::string::npos) {
        continue;
      }
      if (line.find(log.c_str()) != std::string::npos) {
        continue;
      }

      line = std::regex_replace(line, std::regex("Files "), "");
      line = std::regex_replace(line, std::regex("differ"), "");
      std::cout << line << std::endl;
    }
  }

  clp->printFooter();
  int nbFatal = atoi(readUnitResult.m_nbFatal.c_str()) +
                atoi(readAllResult.m_nbFatal.c_str());
  // m.unlock();
  return std::make_pair(retval != -1, !nbFatal);
}
