#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);
      } else if (type == "coverage_dir") {
        this->LoadCoverageData(path);
      } 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(std::string const& 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);
    name.erase(name.size() - 2);
    this->RoutineToDirectory[name] = 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;
}
