#include "cmParseDelphiCoverage.h"

#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
#include "cmSystemTools.h"

#include <cmsys/FStream.hxx>
#include <cmsys/Glob.hxx>
#include <stdio.h>
#include <stdlib.h>

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

  virtual ~HTMLParser() {}

  bool initializeDelphiFile(
    std::string const& 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(
  std::vector<std::string> const& 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;
}
