/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmParseBlanketJSCoverage.h"

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

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

class cmParseBlanketJSCoverage::JSONParser
{
public:
  typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector
    FileLinesType;
  JSONParser(cmCTestCoverageHandlerContainer& cont)
    : Coverage(cont)
  {
  }

  virtual ~JSONParser() {}

  std::string getValue(std::string const& line, int type)
  {
    size_t begIndex;
    size_t endIndex;
    endIndex = line.rfind(',');
    begIndex = line.find_first_of(':');
    if (type == 0) {
      //  A unique substring to remove the extra characters
      //  around the files name in the JSON (extra " and ,)
      std::string foundFileName =
        line.substr(begIndex + 3, endIndex - (begIndex + 4));
      return foundFileName;
    }
    return line.substr(begIndex);
  }
  bool ParseFile(std::string const& file)
  {
    FileLinesType localCoverageVector;
    std::string filename;
    bool foundFile = false;
    bool inSource = false;
    std::string covResult;
    std::string line;

    cmsys::ifstream in(file.c_str());
    if (!in) {
      return false;
    }
    while (cmSystemTools::GetLineFromStream(in, line)) {
      if (line.find("filename") != std::string::npos) {
        if (foundFile) {
          /*
           * Upon finding a second file name, generate a
           * vector within the total coverage to capture the
           * information in the local vector
           */
          FileLinesType& CoverageVector =
            this->Coverage.TotalCoverage[filename];
          CoverageVector = localCoverageVector;
          localCoverageVector.clear();
        }
        foundFile = true;
        inSource = false;
        filename = getValue(line, 0);
      } else if ((line.find("coverage") != std::string::npos) && foundFile &&
                 inSource) {
        /*
         *  two types of "coverage" in the JSON structure
         *
         *  The coverage result over the file or set of files
         *  and the coverage for each individual line
         *
         *  FoundFile and foundSource ensure that
         *  only the value of the line coverage is captured
         */
        std::string result = getValue(line, 1);
        result = result.substr(2);
        if (result == "\"\"") {
          // Empty quotation marks indicate that the
          // line is not executable
          localCoverageVector.push_back(-1);
        } else {
          // Else, it contains the number of time executed
          localCoverageVector.push_back(atoi(result.c_str()));
        }
      } else if (line.find("source") != std::string::npos) {
        inSource = true;
      }
    }

    // On exit, capture end of last file covered.
    FileLinesType& CoverageVector = this->Coverage.TotalCoverage[filename];
    CoverageVector = localCoverageVector;
    localCoverageVector.clear();
    return true;
  }

private:
  cmCTestCoverageHandlerContainer& Coverage;
};

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

bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files)
{
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     "Found " << files.size() << " Files" << std::endl,
                     this->Coverage.Quiet);
  for (std::string const& file : files) {
    cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                       "Reading JSON File " << file << std::endl,
                       this->Coverage.Quiet);

    if (!this->ReadJSONFile(file)) {
      return false;
    }
  }
  return true;
}

bool cmParseBlanketJSCoverage::ReadJSONFile(std::string const& file)
{
  cmParseBlanketJSCoverage::JSONParser parser(this->Coverage);
  cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
                     "Parsing " << file << std::endl, this->Coverage.Quiet);
  parser.ParseFile(file);
  return true;
}
