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


class cmParseDelphiCoverage::HTMLParser
{
public:
  typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
  FileLinesType;
  HTMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont)
     : CTest(ctest), Coverage(cont)
    {
    }

  virtual ~HTMLParser()
    {
    }

  bool initializeDelphiFile(const std::string filename,
     cmParseDelphiCoverage::HTMLParser::FileLinesType &coverageVector)
    {
    std::string line;
    size_t comPos;
    size_t semiPos;
    bool blockComFlag= false;
    bool lineComFlag= false;
    std::vector<std::string> beginSet;
    cmsys::ifstream in(filename.c_str());
    if(!in)
      {
      return false;
      }
    while(cmSystemTools::GetLineFromStream(in, line))
      {
      lineComFlag=false;
      // Unique cases found in lines.
      size_t beginPos = line.find("begin");

      //Check that the begin is the first non-space string on the line
      if( (beginPos == line.find_first_not_of(' ')) && beginPos != line.npos )
        {
        beginSet.push_back("begin");
        coverageVector.push_back(-1);
        continue;
        }
      else if(line.find('{') != line.npos)
        {
        blockComFlag=true;
        }
      else if(line.find('}') != line.npos)
        {
        blockComFlag=false;
        coverageVector.push_back(-1);
        continue;
        }
      else if((line.find("end;") != line.npos)
         && !beginSet.empty())
        {
        beginSet.pop_back();
        coverageVector.push_back(-1);
        continue;
        }

      //  This checks for comments after lines of code, finding the
      //  comment symbol after the ending semicolon.
      comPos = line.find("//");
      if(comPos != line.npos)
        {
        semiPos= line.find(';');
        if(comPos < semiPos)
          {
          lineComFlag=true;
          }
        }
      //Based up what was found, add a line to the coverageVector
      if(!beginSet.empty() && line != ""  && !blockComFlag
         && !lineComFlag)
        {
        coverageVector.push_back(0);
        }
      else
        {
        coverageVector.push_back(-1);
        }
      }
      return true;
    }
  bool ParseFile(const char* file)
    {
    std::string line=file;
    std::string lineresult;
    std::string lastroutine;
    std::string filename;
    std::string filelineoffset;
    size_t afterLineNum = 0;
    size_t lastoffset = 0;
    size_t endcovpos = 0;
    size_t endnamepos = 0;
    size_t pos = 0;

    /*
    *  This first 'while' section goes through the found HTML
    *  file name and attempts to capture the source file name
    *   which is set as part of the HTML file name: the name of
    *   the file is found in parenthesis '()'
    *
    *   See test HTML file name: UTCovTest(UTCovTest.pas).html.
    *
    *   Find the text inside each pair of parenthesis and check
    *   to see if it ends in '.pas'.  If it can't be found,
    *   exit the function.
    */
    while(true)
      {
      lastoffset = line.find('(',pos);
      if(lastoffset==line.npos)
        {
        cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
           endnamepos << "File not found  " << lastoffset  << std::endl,
           this->Coverage.Quiet);
        return false;
        }
      endnamepos = line.find(')',lastoffset);
      filename = line.substr(lastoffset+1,
         (endnamepos-1)-lastoffset);
      if(filename.find(".pas") != filename.npos)
        {
        cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
           "Coverage found for file:  " << filename  << std::endl,
           this->Coverage.Quiet);
        break;
        }
      pos = lastoffset+1;
      }
    /*
    *  Glob through the source directory for the
    *  file found above
    */
    cmsys::Glob gl;
    gl.RecurseOn();
    gl.RecurseThroughSymlinksOff();
    std::string glob = Coverage.SourceDir + "*/" + filename;
    gl.FindFiles(glob);
    std::vector<std::string> const& files = gl.GetFiles();
    if(files.empty())
      {
      /*
      *  If that doesn't find any matching files
      *  return a failure.
      */
      cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
         "Unable to find file matching" << glob << std::endl,
         this->Coverage.Quiet);
      return false;
      }
    FileLinesType&  coverageVector =
       this->Coverage.TotalCoverage[files[0]];

    /*
    *  Initialize the file to have all code between 'begin' and
    *  'end' tags marked as executable
    */

    this->initializeDelphiFile(files[0],coverageVector);

    cmsys::ifstream in(file);
    if(!in)
      {
      return false;
      }

    /*
    *  Now read the HTML file, looking for the lines that have an
    *  "inline" in it. Then parse out the "class" value of that
    *  line to determine if the line is executed or not.
    *
    *  Sample HTML line:
    *
    *  <tr class="covered"><td>47</td><td><pre style="display:inline;">
    *    &nbsp;CheckEquals(1,2-1);</pre></td></tr>
    *
    */

    while(  cmSystemTools::GetLineFromStream(in, line))
      {
      if(line.find("inline") == line.npos)
        {
        continue;
        }

      lastoffset = line.find("class=");
      endcovpos = line.find(">",lastoffset);
      lineresult = line.substr(lastoffset+7,(endcovpos-8)-lastoffset);

      if(lineresult == "covered")
        {
        afterLineNum = line.find('<',endcovpos+5);
        filelineoffset= line.substr(endcovpos+5,
        afterLineNum-(endcovpos+5));
        coverageVector[atoi(filelineoffset.c_str())-1] = 1;
        }
      }
      return true;
    }


  private:
    cmCTest* CTest;
    cmCTestCoverageHandlerContainer& Coverage;
};

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

bool cmParseDelphiCoverage::LoadCoverageData(
  const std::vector<std::string> files)
  {
  size_t i;
  std::string path;
  size_t numf = files.size();
  for (i = 0; i < numf; i++)
    {
    path = files[i];

    cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT,
       "Reading HTML File " << path  << std::endl, this->Coverage.Quiet);
    if(cmSystemTools::GetFilenameLastExtension(path) == ".html")
      {
      if(!this->ReadDelphiHTML(path.c_str()))
        {
        return false;
        }
      }
    }
  return true;
  }

bool cmParseDelphiCoverage::ReadDelphiHTML(const char* file)
  {
  cmParseDelphiCoverage::HTMLParser
     parser(this->CTest, this->Coverage);
  parser.ParseFile(file);
  return true;
  }
