/* 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 "cmProperty.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.
    cmProp emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
    if (emulator != nullptr && !emulator->empty()) {
      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 << "add_test(\"" << 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() };
}
