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


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.c_str()))
      {
      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(cmCTestCoverageHandlerContainer::SingleFileCoverageVector::iterator i=
          v.begin(); i != v.end(); ++i)
      {
      if(*i > 0)
        {
        nothing = false;
        break;
        }
      }
    if(nothing)
      {
      cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                 "No coverage found in: " << ci->first
                 << std::endl);
      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.size() == 0)
      {
      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 = "";
        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 = ""; // at the end of this routine
        filepath = "";
        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.size() == 0)
      {
      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);
      }
    coverageVector[linenumber] += count;
    }
  return true;
}
