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

#include <sstream>
#include <utility>

#include "cmCTest.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

cmCTestGenericHandler::cmCTestGenericHandler()
{
  HandlerVerbose = cmSystemTools::OUTPUT_NONE;
  CTest = nullptr;
  SubmitIndex = 0;
  AppendXML = false;
  Quiet = false;
  TestLoad = 0;
}

cmCTestGenericHandler::~cmCTestGenericHandler() = default;

void cmCTestGenericHandler::SetOption(const std::string& op, const char* value)
{
  if (!value) {
    auto remit = Options.find(op);
    if (remit != Options.end()) {
      Options.erase(remit);
    }
    return;
  }

  Options[op] = value;
}

void cmCTestGenericHandler::SetPersistentOption(const std::string& op,
                                                const char* value)
{
  SetOption(op, value);
  if (!value) {
    auto remit = PersistentOptions.find(op);
    if (remit != PersistentOptions.end()) {
      PersistentOptions.erase(remit);
    }
    return;
  }

  PersistentOptions[op] = value;
}

void cmCTestGenericHandler::Initialize()
{
  AppendXML = false;
  TestLoad = 0;
  Options.clear();
  for (auto const& po : PersistentOptions) {
    Options[po.first] = po.second;
  }
}

const char* cmCTestGenericHandler::GetOption(const std::string& op)
{
  auto remit = Options.find(op);
  if (remit == Options.end()) {
    return nullptr;
  }
  return remit->second.c_str();
}

bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part,
                                              const char* name,
                                              cmGeneratedFileStream& xofs)
{
  if (!name) {
    cmCTestLog(CTest, ERROR_MESSAGE,
               "Cannot create resulting XML file without providing the name"
                 << std::endl;);
    return false;
  }
  std::ostringstream ostr;
  ostr << name;
  if (SubmitIndex > 0) {
    ostr << "_" << SubmitIndex;
  }
  ostr << ".xml";
  if (CTest->GetCurrentTag().empty()) {
    cmCTestLog(CTest, ERROR_MESSAGE,
               "Current Tag empty, this may mean NightlyStartTime / "
               "CTEST_NIGHTLY_START_TIME was not set correctly. Or "
               "maybe you forgot to call ctest_start() before calling "
               "ctest_configure()."
                 << std::endl);
    cmSystemTools::SetFatalErrorOccured();
    return false;
  }
  if (!CTest->OpenOutputFile(CTest->GetCurrentTag(), ostr.str(), xofs, true)) {
    cmCTestLog(CTest, ERROR_MESSAGE,
               "Cannot create resulting XML file: " << ostr.str()
                                                    << std::endl);
    return false;
  }
  CTest->AddSubmitFile(part, ostr.str());
  return true;
}

bool cmCTestGenericHandler::StartLogFile(const char* name,
                                         cmGeneratedFileStream& xofs)
{
  if (!name) {
    cmCTestLog(CTest, ERROR_MESSAGE,
               "Cannot create log file without providing the name"
                 << std::endl;);
    return false;
  }
  std::ostringstream ostr;
  ostr << "Last" << name;
  if (SubmitIndex > 0) {
    ostr << "_" << SubmitIndex;
  }
  if (!CTest->GetCurrentTag().empty()) {
    ostr << "_" << CTest->GetCurrentTag();
  }
  ostr << ".log";
  LogFileNames[name] =
    cmStrCat(CTest->GetBinaryDir(), "/Testing/Temporary/", ostr.str());
  if (!CTest->OpenOutputFile("Temporary", ostr.str(), xofs)) {
    cmCTestLog(CTest, ERROR_MESSAGE,
               "Cannot create log file: " << ostr.str() << std::endl);
    return false;
  }
  return true;
}
