#include "cmParseMumpsCoverage.h"

#include <map>
#include <string>
#include <utility>
#include <vector>

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

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

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

cmParseMumpsCoverage::~cmParseMumpsCoverage() = default;

bool cmParseMumpsCoverage::ReadCoverageFile(const char* file)
{
  // Read the gtm_coverage.mcov file, that has two lines of data:
  // packages:/full/path/to/Vista/Packages
  // coverage_dir:/full/path/to/dir/with/*.mcov
  cmsys::ifstream in(file);
  if (!in) {
    return false;
  }
  std::string line;
  while (cmSystemTools::GetLineFromStream(in, line)) {
    std::string::size_type pos = line.find(':', 0);
    std::string packages;
    if (pos != std::string::npos) {
      std::string type = line.substr(0, pos);
      std::string path = line.substr(pos + 1);
      if (type == "packages") {
        this->LoadPackages(path.c_str());
      } else if (type == "coverage_dir") {
        this->LoadCoverageData(path.c_str());
      } else {
        cmCTestLog(this->CTest, ERROR_MESSAGE,
                   "Parse Error in Mumps coverage file :\n"
                     << file << "\ntype: [" << type << "]\npath:[" << path
                     << "]\n"
                        "input line: ["
                     << line << "]\n");
      }
    }
  }
  return true;
}

void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
{
  // initialize the coverage information for a given mumps file
  cmsys::ifstream in(file.c_str());
  if (!in) {
    return;
  }
  std::string line;
  cmCTestCoverageHandlerContainer::SingleFileCoverageVector& coverageVector =
    this->Coverage.TotalCoverage[file];
  if (!cmSystemTools::GetLineFromStream(in, line)) {
    return;
  }
  // first line of a .m file can never be run
  coverageVector.push_back(-1);
  while (cmSystemTools::GetLineFromStream(in, line)) {
    // putting in a 0 for a line means it is executable code
    // putting in a -1 for a line means it is not executable code
    int val = -1; // assume line is not executable
    bool found = false;
    std::string::size_type i = 0;
    // (1) Search for the first whitespace or semicolon character on a line.
    // This will skip over labels if the line starts with one, or will simply
    // be the first character on the line for non-label lines.
    for (; i < line.size(); ++i) {
      if (line[i] == ' ' || line[i] == '\t' || line[i] == ';') {
        found = true;
        break;
      }
    }
    if (found) {
      // (2) If the first character found above is whitespace or a period
      // then continue the search for the first following non-whitespace
      // character.
      if (line[i] == ' ' || line[i] == '\t') {
        while (i < line.size() &&
               (line[i] == ' ' || line[i] == '\t' || line[i] == '.')) {
          i++;
        }
      }
      // (3) If the character found is not a semicolon then the line counts for
      // coverage.
      if (i < line.size() && line[i] != ';') {
        val = 0;
      }
    }
    coverageVector.push_back(val);
  }
}

bool cmParseMumpsCoverage::LoadPackages(const char* d)
{
  cmsys::Glob glob;
  glob.RecurseOn();
  std::string pat = cmStrCat(d, "/*.m");
  glob.FindFiles(pat);
  for (std::string& file : glob.GetFiles()) {
    std::string name = cmSystemTools::GetFilenameName(file);
    this->RoutineToDirectory[name.substr(0, name.size() - 2)] = file;
    // initialize each file, this is left out until CDash is fixed
    // to handle large numbers of files
    this->InitializeMumpsFile(file);
  }
  return true;
}

bool cmParseMumpsCoverage::FindMumpsFile(std::string const& routine,
                                         std::string& filepath)
{
  auto i = this->RoutineToDirectory.find(routine);
  if (i != this->RoutineToDirectory.end()) {
    filepath = i->second;
    return true;
  }
  // try some alternate names
  const char* tryname[] = { "GUX", "GTM", "ONT", nullptr };
  for (int k = 0; tryname[k] != nullptr; k++) {
    std::string routine2 = routine + tryname[k];
    i = this->RoutineToDirectory.find(routine2);
    if (i != this->RoutineToDirectory.end()) {
      filepath = i->second;
      return true;
    }
  }
  return false;
}
