#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() = default;

  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.emplace_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;
}
