#include "cmStandardIncludes.h"
#include <stdio.h>
#include <stdlib.h>
#include "cmSystemTools.h"
#include "cmParseGTMCoverage.h"
#include <cmsys/Directory.hxx>
#include <cmsys/Glob.hxx>
#include <cmsys/FStream.hxx>


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.c_str()))
      {
      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") == line.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.size())
        {
        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];
        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.c_str());
    if(pos == 0)
      {
      char nextchar = line[function.size()];
      if(nextchar == ' ' || nextchar == '(')
        {
        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<cmStdString> 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 = "";
      // 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 == line.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)
    {
    linenumber = 0;
    }
  else
    {
    // this is the format for this line
    // ^COVERAGE("%RSEL","SRC",count)
    linenumber = atoi(args[2].c_str());
    }
  return true;
}
