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

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

#include <map>
#include <string>
#include <vector>

#include <stddef.h>

#include "cmCTest.h"
#include "cmSystemTools.h"
#include "cmValue.h"

class cmGeneratedFileStream;
class cmMakefile;

/** \class cmCTestGenericHandler
 * \brief A superclass of all CTest Handlers
 *
 */
class cmCTestGenericHandler
{
public:
  /**
   * If verbose then more information is printed out
   */
  void SetVerbose(bool val)
  {
    this->HandlerVerbose =
      val ? cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE;
  }

  /**
   * Populate internals from CTest custom scripts
   */
  virtual void PopulateCustomVectors(cmMakefile*) {}

  /**
   * Do the actual processing. Subclass has to override it.
   * Return < 0 if error.
   */
  virtual int ProcessHandler() = 0;

  /**
   * Process command line arguments that are applicable for the handler
   */
  virtual int ProcessCommandLineArguments(
    const std::string& /*currentArg*/, size_t& /*idx*/,
    const std::vector<std::string>& /*allArgs*/)
  {
    return 1;
  }

  /**
   * Initialize handler
   */
  virtual void Initialize();

  /**
   * Set the CTest instance
   */
  void SetCTestInstance(cmCTest* ctest) { this->CTest = ctest; }
  cmCTest* GetCTestInstance() { return this->CTest; }

  /**
   * Construct handler
   */
  cmCTestGenericHandler();
  virtual ~cmCTestGenericHandler();

  using t_StringToString = std::map<std::string, std::string>;
  using t_StringToMultiString =
    std::map<std::string, std::vector<std::string>>;

  /**
   * Options collect a single value from flags; passing the
   * flag multiple times on the command-line *overwrites* values,
   * and only the last one specified counts. Set an option to
   * nullptr to "unset" it.
   *
   * The value is stored as a string. The values set for single
   * and multi-options (see below) live in different spaces,
   * so calling a single-getter for a key that has only been set
   * as a multi-value will return nullptr.
   */
  void SetPersistentOption(const std::string& op, const char* value);
  void SetPersistentOption(const std::string& op, const std::string& value)
  {
    this->SetPersistentOption(op, cmValue(value));
  }
  void SetPersistentOption(const std::string& op, cmValue value);
  void SetOption(const std::string& op, const char* value);
  void SetOption(const std::string& op, const std::string& value)
  {
    this->SetOption(op, cmValue(value));
  }
  void SetOption(const std::string& op, cmValue value);
  cmValue GetOption(const std::string& op);

  /**
   * Multi-Options collect one or more values from flags; passing
   * the flag multiple times on the command-line *adds* values,
   * rather than overwriting the previous values.
   *
   * Adding an empty value does nothing.
   *
   * The value is stored as a vector of strings. The values set for single
   * (see above) and multi-options live in different spaces,
   * so calling a multi-getter for a key that has only been set
   * as a single-value will return an empty vector.
   */
  void AddPersistentMultiOption(const std::string& optionName,
                                const std::string& value);
  void AddMultiOption(const std::string& optionName, const std::string& value);
  std::vector<std::string> GetMultiOption(const std::string& op) const;

  void SetSubmitIndex(int idx) { this->SubmitIndex = idx; }
  int GetSubmitIndex() { return this->SubmitIndex; }

  void SetAppendXML(bool b) { this->AppendXML = b; }
  void SetQuiet(bool b) { this->Quiet = b; }
  bool GetQuiet() { return this->Quiet; }
  void SetTestLoad(unsigned long load) { this->TestLoad = load; }
  unsigned long GetTestLoad() const { return this->TestLoad; }

protected:
  bool StartResultingXML(cmCTest::Part part, const char* name,
                         cmGeneratedFileStream& xofs);
  bool StartLogFile(const char* name, cmGeneratedFileStream& xofs);

  bool AppendXML;
  bool Quiet;
  unsigned long TestLoad;
  cmSystemTools::OutputOption HandlerVerbose;
  cmCTest* CTest;
  t_StringToString Options;
  t_StringToString PersistentOptions;
  t_StringToMultiString MultiOptions;
  t_StringToMultiString PersistentMultiOptions;
  t_StringToString LogFileNames;

  int SubmitIndex;
};
