#include "cmParseCacheCoverage.h"

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

#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include <map>
#include <stdio.h>
#include <stdlib.h>
#include <utility>

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

bool cmParseCacheCoverage::LoadCoverageData(const char* 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 = d;
      path += "/";
      path += 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.
  cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator 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 (separateLine[0].substr(0, 6) == "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;
}
