#include "cmParseDelphiCoverage.h"

#include <cstdio>
#include <cstdlib>

#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"

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

class cmParseDelphiCoverage::HTMLParser
{
public:
  using FileLinesType =
    cmCTestCoverageHandlerContainer::SingleFileCoverageVector;
  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;
}
