#include "cmParseGTMCoverage.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 <vector>

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

bool cmParseGTMCoverage::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) == ".mcov") {
        if (!this->ReadMCovFile(path.c_str())) {
          return false;
        }
      }
    }
  }
  return true;
}

bool cmParseGTMCoverage::ReadMCovFile(const char* file)
{
  cmsys::ifstream in(file);
  if (!in) {
    return false;
  }
  std::string line;
  std::string lastfunction;
  std::string lastroutine;
  std::string lastpath;
  int lastoffset = 0;
  while (cmSystemTools::GetLineFromStream(in, line)) {
    // only look at lines that have coverage data
    if (line.find("^ZZCOVERAGE") == std::string::npos) {
      continue;
    }
    std::string filepath;
    std::string function;
    std::string routine;
    int linenumber = 0;
    int count = 0;
    this->ParseMCOVLine(line, routine, function, linenumber, count);
    // skip this one
    if (routine == "RSEL") {
      continue;
    }
    // no need to search the file if we just did it
    if (function == lastfunction && lastroutine == routine) {
      if (!lastpath.empty()) {
        this->Coverage.TotalCoverage[lastpath][lastoffset + linenumber] +=
          count;
      } else {
        cmCTestLog(this->CTest, ERROR_MESSAGE, "Can not find mumps file : "
                     << lastroutine
                     << "  referenced in this line of mcov data:\n"
                        "["
                     << line << "]\n");
      }
      continue;
    }
    // Find the full path to the file
    bool found = this->FindMumpsFile(routine, filepath);
    if (found) {
      int lineoffset = 0;
      if (this->FindFunctionInMumpsFile(filepath, function, lineoffset)) {
        cmCTestCoverageHandlerContainer::SingleFileCoverageVector&
          coverageVector = this->Coverage.TotalCoverage[filepath];
        // This section 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 addtion to the count found.
        if (coverageVector[lineoffset + linenumber] == -1 && count > 0) {
          coverageVector[lineoffset + linenumber] += count + 1;
        } else {
          coverageVector[lineoffset + linenumber] += count;
        }
        lastoffset = lineoffset;
      }
    } else {
      cmCTestLog(this->CTest, ERROR_MESSAGE, "Can not find mumps file : "
                   << routine << "  referenced in this line of mcov data:\n"
                                 "["
                   << line << "]\n");
    }
    lastfunction = function;
    lastroutine = routine;
    lastpath = filepath;
  }
  return true;
}

bool cmParseGTMCoverage::FindFunctionInMumpsFile(std::string const& filepath,
                                                 std::string const& function,
                                                 int& lineoffset)
{
  cmsys::ifstream in(filepath.c_str());
  if (!in) {
    return false;
  }
  std::string line;
  int linenum = 0;
  while (cmSystemTools::GetLineFromStream(in, line)) {
    std::string::size_type pos = line.find(function);
    if (pos == 0) {
      char nextchar = line[function.size()];
      if (nextchar == ' ' || nextchar == '(' || nextchar == '\t') {
        lineoffset = linenum;
        return true;
      }
    }
    if (pos == 1) {
      char prevchar = line[0];
      char nextchar = line[function.size() + 1];
      if (prevchar == '%' && (nextchar == ' ' || nextchar == '(')) {
        lineoffset = linenum;
        return true;
      }
    }
    linenum++; // move to next line count
  }
  lineoffset = 0;
  cmCTestLog(this->CTest, ERROR_MESSAGE, "Could not find entry point : "
               << function << " in " << filepath << "\n");
  return false;
}

bool cmParseGTMCoverage::ParseMCOVLine(std::string const& line,
                                       std::string& routine,
                                       std::string& function, int& linenumber,
                                       int& count)
{
  // this method parses lines from the .mcov file
  // each line has ^COVERAGE(...) in it, and there
  // are several varients of coverage lines:
  //
  // ^COVERAGE("DIC11","PR1",0)="2:0:0:0"
  //          ( file  , entry, line ) = "number_executed:timing_info"
  // ^COVERAGE("%RSEL","SRC")="1:0:0:0"
  //          ( file  , entry ) = "number_executed:timing_info"
  // ^COVERAGE("%RSEL","init",8,"FOR_LOOP",1)=1
  //          ( file  , entry, line, IGNORE ) =number_executed
  std::vector<std::string> args;
  std::string::size_type pos = line.find('(', 0);
  // if no ( is found, then return line has no coverage
  if (pos == std::string::npos) {
    return false;
  }
  std::string arg;
  bool done = false;
  // separate out all of the comma separated arguments found
  // in the COVERAGE(...) line
  while (line[pos] && !done) {
    // save the char we are looking at
    char cur = line[pos];
    // , or ) means end of argument
    if (cur == ',' || cur == ')') {
      // save the argument into the argument vector
      args.push_back(arg);
      // start on a new argument
      arg.clear();
      // if we are at the end of the ), then finish while loop
      if (cur == ')') {
        done = true;
      }
    } else {
      // all chars except ", (, and % get stored in the arg string
      if (cur != '\"' && cur != '(' && cur != '%') {
        arg.append(1, line[pos]);
      }
    }
    // move to next char
    pos++;
  }
  // now parse the right hand side of the =
  pos = line.find('=');
  // no = found, this is an error
  if (pos == std::string::npos) {
    return false;
  }
  pos++; // move past =

  // if the next positing is not a ", then this is a
  // COVERAGE(..)=count line and turn the rest of the string
  // past the = into an integer and set it to count
  if (line[pos] != '\"') {
    count = atoi(line.substr(pos).c_str());
  } else {
    // this means line[pos] is a ", and we have a
    // COVERAGE(...)="1:0:0:0" type of line
    pos++; // move past "
    // find the first : past the "
    std::string::size_type pos2 = line.find(':', pos);
    // turn the string between the " and the first : into an integer
    // and set it to count
    count = atoi(line.substr(pos, pos2 - pos).c_str());
  }
  // less then two arguments is an error
  if (args.size() < 2) {
    cmCTestLog(this->CTest, ERROR_MESSAGE, "Error parsing mcov line: ["
                 << line << "]\n");
    return false;
  }
  routine = args[0];  // the routine is the first argument
  function = args[1]; // the function in the routine is the second
  // in the two argument only format
  // ^COVERAGE("%RSEL","SRC"), the line offset is 0
  if (args.size() == 2) {
    // To avoid double counting of line 0 of each entry point,
    // Don't count the lines that do not give an explicit line
    // number.
    routine.clear();
    function.clear();
  } else {
    // this is the format for this line
    // ^COVERAGE("%RSEL","SRC",count)
    linenumber = atoi(args[2].c_str());
  }
  return true;
}
