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

#include <memory>
#include <ostream>
#include <utility>
#include <vector>

#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmOutputConverter.h"
#include "cmPropertyMap.h"
#include "cmRange.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTest.h"

cmTestGenerator::cmTestGenerator(
  cmTest* test, std::vector<std::string> const& configurations)
  : cmScriptGenerator("CTEST_CONFIGURATION_TYPE", configurations)
  , Test(test)
{
  this->ActionsPerConfig = !test->GetOldStyle();
  this->TestGenerated = false;
  this->LG = nullptr;
}

cmTestGenerator::~cmTestGenerator() = default;

void cmTestGenerator::Compute(cmLocalGenerator* lg)
{
  this->LG = lg;
}

bool cmTestGenerator::TestsForConfig(const std::string& config)
{
  return this->GeneratesForConfig(config);
}

cmTest* cmTestGenerator::GetTest() const
{
  return this->Test;
}

void cmTestGenerator::GenerateScriptConfigs(std::ostream& os, Indent indent)
{
  // Create the tests.
  this->cmScriptGenerator::GenerateScriptConfigs(os, indent);
}

void cmTestGenerator::GenerateScriptActions(std::ostream& os, Indent indent)
{
  if (this->ActionsPerConfig) {
    // This is the per-config generation in a single-configuration
    // build generator case.  The superclass will call our per-config
    // method.
    this->cmScriptGenerator::GenerateScriptActions(os, indent);
  } else {
    // This is an old-style test, so there is only one config.
    // assert(this->Test->GetOldStyle());
    this->GenerateOldStyle(os, indent);
  }
}

void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
                                              const std::string& config,
                                              Indent indent)
{
  this->TestGenerated = true;

  // Set up generator expression evaluation context.
  cmGeneratorExpression ge(this->Test->GetBacktrace());

  // Start the test command.
  os << indent << "add_test(" << this->Test->GetName() << " ";

  // Evaluate command line arguments
  std::vector<std::string> argv =
    EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config);

  // Expand arguments if COMMAND_EXPAND_LISTS is set
  if (this->Test->GetCommandExpandLists()) {
    argv = cmExpandedLists(argv.begin(), argv.end());
    // Expanding lists on an empty command may have left it empty
    if (argv.empty()) {
      argv.emplace_back();
    }
  }

  // Check whether the command executable is a target whose name is to
  // be translated.
  std::string exe = argv[0];
  cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(exe);
  if (target && target->GetType() == cmStateEnums::EXECUTABLE) {
    // Use the target file on disk.
    exe = target->GetFullPath(config);

    // Prepend with the emulator when cross compiling if required.
    const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
    if (emulator != nullptr && *emulator) {
      std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
      std::string emulatorExe(emulatorWithArgs[0]);
      cmSystemTools::ConvertToUnixSlashes(emulatorExe);
      os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
      for (std::string const& arg : cmMakeRange(emulatorWithArgs).advance(1)) {
        os << cmOutputConverter::EscapeForCMake(arg) << " ";
      }
    }
  } else {
    // Use the command name given.
    cmSystemTools::ConvertToUnixSlashes(exe);
  }

  // Generate the command line with full escapes.
  os << cmOutputConverter::EscapeForCMake(exe);

  for (auto const& arg : cmMakeRange(argv).advance(1)) {
    os << " " << cmOutputConverter::EscapeForCMake(arg);
  }

  // Finish the test command.
  os << ")\n";

  // Output properties for the test.
  os << indent << "set_tests_properties(" << this->Test->GetName()
     << " PROPERTIES ";
  for (auto const& i : this->Test->GetProperties().GetList()) {
    os << " " << i.first << " "
       << cmOutputConverter::EscapeForCMake(
            ge.Parse(i.second)->Evaluate(this->LG, config));
  }
  this->GenerateInternalProperties(os);
  os << ")\n";
}

void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent)
{
  os << indent << "add_test(" << this->Test->GetName() << " NOT_AVAILABLE)\n";
}

bool cmTestGenerator::NeedsScriptNoConfig() const
{
  return (this->TestGenerated &&    // test generated for at least one config
          this->ActionsPerConfig && // test is config-aware
          this->Configurations.empty() &&      // test runs in all configs
          !this->ConfigurationTypes->empty()); // config-dependent command
}

void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
{
  this->TestGenerated = true;

  // Get the test command line to be executed.
  std::vector<std::string> const& command = this->Test->GetCommand();

  std::string exe = command[0];
  cmSystemTools::ConvertToUnixSlashes(exe);
  fout << indent;
  fout << "add_test(";
  fout << this->Test->GetName() << " \"" << exe << "\"";

  for (std::string const& arg : cmMakeRange(command).advance(1)) {
    // Just double-quote all arguments so they are re-parsed
    // correctly by the test system.
    fout << " \"";
    for (char c : arg) {
      // Escape quotes within arguments.  We should escape
      // backslashes too but we cannot because it makes the result
      // inconsistent with previous behavior of this command.
      if (c == '"') {
        fout << '\\';
      }
      fout << c;
    }
    fout << '"';
  }
  fout << ")\n";

  // Output properties for the test.
  fout << indent << "set_tests_properties(" << this->Test->GetName()
       << " PROPERTIES ";
  for (auto const& i : this->Test->GetProperties().GetList()) {
    fout << " " << i.first << " "
         << cmOutputConverter::EscapeForCMake(i.second);
  }
  this->GenerateInternalProperties(fout);
  fout << ")\n";
}

void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
{
  cmListFileBacktrace bt = this->Test->GetBacktrace();
  if (bt.Empty()) {
    return;
  }

  os << " "
     << "_BACKTRACE_TRIPLES"
     << " \"";

  bool prependTripleSeparator = false;
  while (!bt.Empty()) {
    const auto& entry = bt.Top();
    if (prependTripleSeparator) {
      os << ";";
    }
    os << entry.FilePath << ";" << entry.Line << ";" << entry.Name;
    bt = bt.Pop();
    prependTripleSeparator = true;
  }

  os << '"';
}

std::vector<std::string> cmTestGenerator::EvaluateCommandLineArguments(
  const std::vector<std::string>& argv, cmGeneratorExpression& ge,
  const std::string& config) const
{
  // Evaluate executable name and arguments
  auto evaluatedRange =
    cmMakeRange(argv).transform([&](const std::string& arg) {
      return ge.Parse(arg)->Evaluate(this->LG, config);
    });

  return { evaluatedRange.begin(), evaluatedRange.end() };
}
