#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 != std::string::npos) {
        beginSet.push_back("begin");
        coverageVector.push_back(-1);
        continue;
      }
      if (line.find('{') != std::string::npos) {
        blockComFlag = true;
      } else if (line.find('}') != std::string::npos) {
        blockComFlag = false;
        coverageVector.push_back(-1);
        continue;
      } else if ((line.find("end;") != std::string::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 != std::string::npos) {
        semiPos = line.find(';');
        if (comPos < semiPos) {
          lineComFlag = true;
        }
      }
      // Based up what was found, add a line to the coverageVector
      if (!beginSet.empty() && !line.empty() && !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 == std::string::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") != std::string::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") == std::string::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;
}
