#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>


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

cmParseMumpsCoverage::~cmParseMumpsCoverage()
{
}

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 = d;
  pat += "/*.m";
  glob.FindFiles(pat);
  std::vector<std::string>& files = glob.GetFiles();
  std::vector<std::string>::iterator fileIt;
  for ( fileIt = files.begin(); fileIt != files.end();
        ++ fileIt )
    {
    std::string name = cmSystemTools::GetFilenameName(*fileIt);
    this->RoutineToDirectory[name.substr(0, name.size()-2)] = *fileIt;
    // initialze each file, this is left out until CDash is fixed
    // to handle large numbers of files
    this->InitializeMumpsFile(*fileIt);
    }
  return true;
}

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