#include "cmParseCacheCoverage.h"

#include <cstdio>
#include <cstdlib>
#include <map>
#include <utility>

#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"

#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

cmParseCacheCoverage::cmParseCacheCoverage(
  cmCTestCoverageHandlerContainer& cont, cmCTest* ctest)
  : cmParseMumpsCoverage(cont, ctest)
{
}

bool cmParseCacheCoverage::LoadCoverageData(std::string const& d)
{
  // load all the .mcov files in the specified directory
  cmsys::Directory dir;
  if (!dir.Load(d)) {
    return false;
  }
  size_t numf;
  unsigned int i;
  numf = dir.GetNumberOfFiles();
  for (i = 0; i < numf; i++) {
    std::string file = dir.GetFile(i);
    if (file != "." && file != ".." && !cmSystemTools::FileIsDirectory(file)) {
      std::string path = cmStrCat(d, '/', file);
      if (cmSystemTools::GetFilenameLastExtension(path) == ".cmcov") {
        if (!this->ReadCMCovFile(path.c_str())) {
          return false;
        }
      }
    }
  }
  return true;
}

// not currently used, but leave it in case we want it in the future
void cmParseCacheCoverage::RemoveUnCoveredFiles()
{
  // loop over the coverage data computed and remove all files
  // that only have -1 or 0 for the lines.
  auto ci = this->Coverage.TotalCoverage.begin();
  while (ci != this->Coverage.TotalCoverage.end()) {
    cmCTestCoverageHandlerContainer::SingleFileCoverageVector& v = ci->second;
    bool nothing = true;
    for (int i : v) {
      if (i > 0) {
        nothing = false;
        break;
      }
    }
    if (nothing) {
      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                         "No coverage found in: " << ci->first << std::endl,
                         this->Coverage.Quiet);
      this->Coverage.TotalCoverage.erase(ci++);
    } else {
      ++ci;
    }
  }
}

bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args,
                                       std::string const& line)
{
  std::string::size_type pos1 = 0;
  std::string::size_type pos2 = line.find(',', 0);
  if (pos2 == std::string::npos) {
    return false;
  }
  std::string arg;
  while (pos2 != std::string::npos) {
    arg = line.substr(pos1, pos2 - pos1);
    args.push_back(arg);
    pos1 = pos2 + 1;
    pos2 = line.find(',', pos1);
  }
  arg = line.substr(pos1);
  args.push_back(arg);
  return true;
}

bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
{
  cmsys::ifstream in(file);
  if (!in) {
    cmCTestLog(this->CTest, ERROR_MESSAGE, "Can not open : " << file << "\n");
    return false;
  }
  std::string line;
  std::vector<std::string> separateLine;
  if (!cmSystemTools::GetLineFromStream(in, line)) {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Empty file : " << file
                               << "  referenced in this line of cmcov data:\n"
                                  "["
                               << line << "]\n");
    return false;
  }
  separateLine.clear();
  this->SplitString(separateLine, line);
  if (separateLine.size() != 4 || separateLine[0] != "Routine" ||
      separateLine[1] != "Line" || separateLine[2] != "RtnLine" ||
      separateLine[3] != "Code") {
    cmCTestLog(this->CTest, ERROR_MESSAGE,
               "Bad first line of cmcov file : " << file
                                                 << "  line:\n"
                                                    "["
                                                 << line << "]\n");
  }
  std::string routine;
  std::string filepath;
  while (cmSystemTools::GetLineFromStream(in, line)) {
    // clear out line argument vector
    separateLine.clear();
    // parse the comma separated line
    this->SplitString(separateLine, line);
    // might have more because code could have a quoted , in it
    // but we only care about the first 3 args anyway
    if (separateLine.size() < 4) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Bad line of cmcov file expected at least 4 found: "
                   << separateLine.size() << " " << file
                   << "  line:\n"
                      "["
                   << line << "]\n");
      for (std::string::size_type i = 0; i < separateLine.size(); ++i) {
        cmCTestLog(this->CTest, ERROR_MESSAGE, "" << separateLine[1] << " ");
      }
      cmCTestLog(this->CTest, ERROR_MESSAGE, "\n");
      return false;
    }
    // if we do not have a routine yet, then it should be
    // the first argument in the vector
    if (routine.empty()) {
      routine = separateLine[0];
      // Find the full path to the file
      if (!this->FindMumpsFile(routine, filepath)) {
        cmCTestLog(this->CTest, ERROR_MESSAGE,
                   "Could not find mumps file for routine: " << routine
                                                             << "\n");
        filepath.clear();
        continue; // move to next line
      }
    }
    // if we have a routine name, check for end of routine
    else {
      // Totals in arg 0 marks the end of a routine
      if (cmHasLiteralPrefix(separateLine[0], "Totals")) {
        routine.clear(); // at the end of this routine
        filepath.clear();
        continue; // move to next line
      }
    }
    // if the file path was not found for the routine
    // move to next line. We should have already warned
    // after the call to FindMumpsFile that we did not find
    // it, so don't report again to cut down on output
    if (filepath.empty()) {
      continue;
    }
    // now we are ready to set the coverage from the line of data
    cmCTestCoverageHandlerContainer::SingleFileCoverageVector& coverageVector =
      this->Coverage.TotalCoverage[filepath];
    std::string::size_type linenumber = atoi(separateLine[1].c_str()) - 1;
    int count = atoi(separateLine[2].c_str());
    if (linenumber > coverageVector.size()) {
      cmCTestLog(this->CTest, ERROR_MESSAGE,
                 "Parse error line is greater than number of lines in file: "
                   << linenumber << " " << filepath << "\n");
      continue; // skip setting count to avoid crash
    }
    // now add to count for linenumber
    // for some reason the cache coverage adds extra lines to the
    // end of the file in some cases. Since they do not exist, we will
    // mark them as non executable
    while (linenumber >= coverageVector.size()) {
      coverageVector.push_back(-1);
    }
    // Accounts for lines that were previously marked
    // as non-executable code (-1). if the parser comes back with
    // a non-zero count, increase the count by 1 to push the line
    // into the executable code set in addition to the count found.
    if (coverageVector[linenumber] == -1 && count > 0) {
      coverageVector[linenumber] += count + 1;
    } else {
      coverageVector[linenumber] += count;
    }
  }
  return true;
}
