/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmCTestMemCheckHandler_h
#define cmCTestMemCheckHandler_h

#include "cmConfigure.h" // IWYU pragma: keep

#include <string>
#include <vector>

#include "cmCTestTestHandler.h"

class cmMakefile;
class cmXMLWriter;

/** \class cmCTestMemCheckHandler
 * \brief A class that handles ctest -S invocations
 *
 */
class cmCTestMemCheckHandler : public cmCTestTestHandler
{
  friend class cmCTestRunTest;

public:
  using Superclass = cmCTestTestHandler;

  void PopulateCustomVectors(cmMakefile* mf) override;

  cmCTestMemCheckHandler();

  void Initialize() override;

  int GetDefectCount();

protected:
  int PreProcessHandler() override;
  int PostProcessHandler() override;
  void GenerateTestCommand(std::vector<std::string>& args, int test) override;

private:
  enum
  { // Memory checkers
    UNKNOWN = 0,
    VALGRIND,
    PURIFY,
    BOUNDS_CHECKER,
    // checkers after here do not use the standard error list
    ADDRESS_SANITIZER,
    LEAK_SANITIZER,
    THREAD_SANITIZER,
    MEMORY_SANITIZER,
    UB_SANITIZER
  };

public:
  enum
  { // Memory faults
    ABR = 0,
    ABW,
    ABWL,
    COR,
    EXU,
    FFM,
    FIM,
    FMM,
    FMR,
    FMW,
    FUM,
    IPR,
    IPW,
    MAF,
    MLK,
    MPK,
    NPR,
    ODS,
    PAR,
    PLK,
    UMC,
    UMR,
    NO_MEMORY_FAULT
  };

private:
  enum
  { // Program statuses
    NOT_RUN = 0,
    TIMEOUT,
    SEGFAULT,
    ILLEGAL,
    INTERRUPT,
    NUMERICAL,
    OTHER_FAULT,
    FAILED,
    BAD_COMMAND,
    COMPLETED
  };
  std::string BoundsCheckerDPBDFile;
  std::string BoundsCheckerXMLFile;
  std::string MemoryTester;
  std::vector<std::string> MemoryTesterDynamicOptions;
  std::vector<std::string> MemoryTesterOptions;
  int MemoryTesterStyle;
  std::string MemoryTesterOutputFile;
  std::string MemoryTesterEnvironmentVariable;
  // these are used to store the types of errors that can show up
  std::vector<std::string> ResultStrings;
  std::vector<std::string> ResultStringsLong;
  std::vector<int> GlobalResults;
  bool LogWithPID; // does log file add pid
  int DefectCount;

  std::vector<int>::size_type FindOrAddWarning(const std::string& warning);
  // initialize the ResultStrings and ResultStringsLong for
  // this type of checker
  void InitializeResultsVectors();

  //! Initialize memory checking subsystem.
  bool InitializeMemoryChecking();

  /**
   * Generate the Dart compatible output
   */
  void GenerateDartOutput(cmXMLWriter& xml) override;

  std::vector<std::string> CustomPreMemCheck;
  std::vector<std::string> CustomPostMemCheck;

  //! Parse Valgrind/Purify/Bounds Checker result out of the output
  // string. After running, log holds the output and results hold the
  // different memory errors.
  bool ProcessMemCheckOutput(const std::string& str, std::string& log,
                             std::vector<int>& results);
  bool ProcessMemCheckValgrindOutput(const std::string& str, std::string& log,
                                     std::vector<int>& results);
  bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log,
                                   std::vector<int>& results);
  bool ProcessMemCheckSanitizerOutput(const std::string& str, std::string& log,
                                      std::vector<int>& results);
  bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
                                          std::string& log,
                                          std::vector<int>& results);

  void PostProcessTest(cmCTestTestResult& res, int test);
  void PostProcessBoundsCheckerTest(cmCTestTestResult& res, int test);

  //! append MemoryTesterOutputFile to the test log
  void AppendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
                             std::string const& filename);

  //! generate the output filename for the given test index
  void TestOutputFileNames(int test, std::vector<std::string>& files);
};

#endif
