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

#include <cstddef>
#include <memory>
#include <utility>

#include <cm/optional>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>

#include "cmCryptoHash.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTargetTypes.h"
#include "cmTransformDepfile.h"
#include "cmValue.h"

namespace {
std::string EvaluateSplitConfigGenex(
  cm::string_view input, cmGeneratorExpression const& ge, cmLocalGenerator* lg,
  bool useOutputConfig, std::string const& outputConfig,
  std::string const& commandConfig, cmGeneratorTarget const* target,
  std::set<BT<std::pair<std::string, bool>>>* utils = nullptr)
{
  std::string result;

  while (!input.empty()) {
    // Copy non-genex content directly to the result.
    std::string::size_type pos = input.find("$<");
    result += input.substr(0, pos);
    if (pos == std::string::npos) {
      break;
    }
    input = input.substr(pos);

    // Find the balanced end of this regex.
    size_t nestingLevel = 1;
    for (pos = 2; pos < input.size(); ++pos) {
      cm::string_view cur = input.substr(pos);
      if (cmHasLiteralPrefix(cur, "$<")) {
        ++nestingLevel;
        ++pos;
        continue;
      }
      if (cmHasPrefix(cur, '>')) {
        --nestingLevel;
        if (nestingLevel == 0) {
          ++pos;
          break;
        }
      }
    }

    // Split this genex from following input.
    cm::string_view genex = input.substr(0, pos);
    input = input.substr(pos);

    // Convert an outer COMMAND_CONFIG or OUTPUT_CONFIG to the matching config.
    std::string const* config =
      useOutputConfig ? &outputConfig : &commandConfig;
    if (nestingLevel == 0) {
      static cm::string_view const COMMAND_CONFIG = "$<COMMAND_CONFIG:"_s;
      static cm::string_view const OUTPUT_CONFIG = "$<OUTPUT_CONFIG:"_s;
      if (cmHasPrefix(genex, COMMAND_CONFIG)) {
        genex.remove_prefix(COMMAND_CONFIG.size());
        genex.remove_suffix(1);
        useOutputConfig = false;
        config = &commandConfig;
      } else if (cmHasPrefix(genex, OUTPUT_CONFIG)) {
        genex.remove_prefix(OUTPUT_CONFIG.size());
        genex.remove_suffix(1);
        useOutputConfig = true;
        config = &outputConfig;
      }
    }

    // Evaluate this genex in the selected configuration.
    std::unique_ptr<cmCompiledGeneratorExpression> cge =
      ge.Parse(std::string(genex));
    result += cge->Evaluate(lg, *config, target);

    // Record targets referenced by the genex.
    if (utils) {
      // Use a cross-dependency if we referenced the command config.
      bool const cross = !useOutputConfig;
      for (cmGeneratorTarget* gt : cge->GetTargets()) {
        utils->emplace(BT<std::pair<std::string, bool>>(
          { gt->GetName(), cross }, cge->GetBacktrace()));
      }
    }
  }

  return result;
}

std::vector<std::string> EvaluateDepends(std::vector<std::string> const& paths,
                                         cmGeneratorExpression const& ge,
                                         cmLocalGenerator* lg,
                                         std::string const& outputConfig,
                                         std::string const& commandConfig)
{
  std::vector<std::string> depends;
  for (std::string const& p : paths) {
    std::string const& ep =
      EvaluateSplitConfigGenex(p, ge, lg, /*useOutputConfig=*/true,
                               /*outputConfig=*/outputConfig,
                               /*commandConfig=*/commandConfig,
                               /*target=*/nullptr);
    cm::append(depends, cmList{ ep });
  }
  for (std::string& p : depends) {
    if (cmSystemTools::FileIsFullPath(p)) {
      p = cmSystemTools::CollapseFullPath(p);
    } else {
      cmSystemTools::ConvertToUnixSlashes(p);
    }
  }
  return depends;
}

std::vector<std::string> EvaluateOutputs(std::vector<std::string> const& paths,
                                         cmGeneratorExpression const& ge,
                                         cmLocalGenerator* lg,
                                         std::string const& config)
{
  std::vector<std::string> outputs;
  for (std::string const& p : paths) {
    std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(p);
    cm::append(outputs, lg->ExpandCustomCommandOutputPaths(*cge, config));
  }
  return outputs;
}

std::string EvaluateDepfile(std::string const& path,
                            cmGeneratorExpression const& ge,
                            cmLocalGenerator* lg, std::string const& config)
{
  std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(path);
  return cge->Evaluate(lg, config);
}

std::string EvaluateComment(char const* comment,
                            cmGeneratorExpression const& ge,
                            cmLocalGenerator* lg, std::string const& config)
{
  std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(comment);
  return cge->Evaluate(lg, config);
}
}

cmCustomCommandGenerator::cmCustomCommandGenerator(
  cmCustomCommand const& cc, std::string config, cmLocalGenerator* lg,
  bool transformDepfile, cm::optional<std::string> crossConfig,
  std::function<std::string(std::string const&, std::string const&)>
    computeInternalDepfile)
  : CC(&cc)
  , OutputConfig(crossConfig ? *crossConfig : config)
  , CommandConfig(std::move(config))
  , Target(cc.GetTarget())
  , LG(lg)
  , OldStyle(cc.GetEscapeOldStyle())
  , MakeVars(cc.GetEscapeAllowMakeVars())
  , EmulatorsWithArguments(cc.GetCommandLines().size())
  , ComputeInternalDepfile(std::move(computeInternalDepfile))
{

  cmGeneratorExpression ge(*lg->GetCMakeInstance(), cc.GetBacktrace());
  cmGeneratorTarget const* target{ lg->FindGeneratorTargetToUse(
    this->Target) };

  bool const distinctConfigs = this->OutputConfig != this->CommandConfig;

  cmCustomCommandLines const& cmdlines = this->CC->GetCommandLines();
  for (cmCustomCommandLine const& cmdline : cmdlines) {
    cmCustomCommandLine argv;
    // For the command itself, we default to the COMMAND_CONFIG.
    bool useOutputConfig = false;
    for (std::string const& clarg : cmdline) {
      std::string parsed_arg = EvaluateSplitConfigGenex(
        clarg, ge, this->LG, useOutputConfig, this->OutputConfig,
        this->CommandConfig, target, &this->Utilities);
      if (this->CC->GetCommandExpandLists()) {
        cm::append(argv, cmList{ parsed_arg });
      } else {
        argv.push_back(std::move(parsed_arg));
      }

      if (distinctConfigs) {
        // For remaining arguments, we default to the OUTPUT_CONFIG.
        useOutputConfig = true;
      }
    }

    if (!argv.empty()) {
      // If the command references an executable target by name,
      // collect the target to add a target-level dependency on it.
      cmGeneratorTarget* gt = this->LG->FindGeneratorTargetToUse(argv.front());
      if (gt && gt->GetType() == cm::TargetType::EXECUTABLE) {
        // GetArgv0Location uses the command config, so use a cross-dependency.
        bool const cross = true;
        this->Utilities.emplace(BT<std::pair<std::string, bool>>(
          { gt->GetName(), cross }, cc.GetBacktrace()));
      }
    } else {
      // Later code assumes at least one entry exists, but expanding
      // lists on an empty command may have left this empty.
      // FIXME: Should we define behavior for removing empty commands?
      argv.emplace_back();
    }

    this->CommandLines.push_back(std::move(argv));
  }

  if (transformDepfile && !this->CommandLines.empty() &&
      !cc.GetDepfile().empty() &&
      this->LG->GetGlobalGenerator()->DepfileFormat()) {
    cmCustomCommandLine argv;
    argv.push_back(cmSystemTools::GetCMakeCommand());
    argv.emplace_back("-E");
    argv.emplace_back("cmake_transform_depfile");
    argv.push_back(this->LG->GetGlobalGenerator()->GetName());
    switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
      case cmDepfileFormat::GccDepfile:
        argv.emplace_back("gccdepfile");
        break;
      case cmDepfileFormat::MakeDepfile:
        argv.emplace_back("makedepfile");
        break;
      case cmDepfileFormat::MSBuildAdditionalInputs:
        argv.emplace_back("MSBuildAdditionalInputs");
        break;
    }
    argv.push_back(this->LG->GetSourceDirectory());
    argv.push_back(this->LG->GetCurrentSourceDirectory());
    argv.push_back(this->LG->GetBinaryDirectory());
    argv.push_back(this->LG->GetCurrentBinaryDirectory());
    argv.push_back(this->GetFullDepfile());
    argv.push_back(this->GetInternalDepfile());

    this->CommandLines.push_back(std::move(argv));
  }

  this->Outputs =
    EvaluateOutputs(cc.GetOutputs(), ge, this->LG, this->OutputConfig);
  this->Byproducts =
    EvaluateOutputs(cc.GetByproducts(), ge, this->LG, this->OutputConfig);
  this->Depends = EvaluateDepends(cc.GetDepends(), ge, this->LG,
                                  this->OutputConfig, this->CommandConfig);

  std::string const& workingdirectory = this->CC->GetWorkingDirectory();
  if (!workingdirectory.empty()) {
    this->WorkingDirectory = EvaluateSplitConfigGenex(
      workingdirectory, ge, this->LG, true, this->OutputConfig,
      this->CommandConfig, target);
    // Convert working directory to a full path.
    if (!this->WorkingDirectory.empty()) {
      std::string const& build_dir = this->LG->GetCurrentBinaryDirectory();
      this->WorkingDirectory =
        cmSystemTools::CollapseFullPath(this->WorkingDirectory, build_dir);
    }
  }

  this->FillEmulatorsWithArguments();
}

unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
{
  return static_cast<unsigned int>(this->CommandLines.size());
}

void cmCustomCommandGenerator::FillEmulatorsWithArguments()
{
  if (!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")) {
    return;
  }
  cmGeneratorExpression ge(*this->LG->GetCMakeInstance(),
                           this->CC->GetBacktrace());

  for (unsigned int c = 0; c < this->GetNumberOfCommands(); ++c) {
    // If the command is the plain name of an executable target,
    // launch it with its emulator.
    std::string const& argv0 = this->CommandLines[c][0];
    cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
    if (target && target->GetType() == cm::TargetType::EXECUTABLE &&
        !target->IsImported()) {

      cmValue emulator_property =
        target->GetProperty("CROSSCOMPILING_EMULATOR");
      if (!emulator_property) {
        continue;
      }

      // Plain target names are replaced by GetArgv0Location with the
      // path to the executable artifact in the command config, so
      // evaluate the launcher's location in the command config too.
      std::string const emulator =
        ge.Parse(*emulator_property)->Evaluate(this->LG, this->CommandConfig);
      cmExpandList(emulator, this->EmulatorsWithArguments[c]);
    }
  }
}

std::vector<std::string> cmCustomCommandGenerator::GetCrossCompilingEmulator(
  unsigned int c) const
{
  if (c >= this->EmulatorsWithArguments.size()) {
    return std::vector<std::string>();
  }
  return this->EmulatorsWithArguments[c];
}

char const* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const
{
  // If the command is the plain name of an executable target, we replace it
  // with the path to the executable artifact in the command config.
  std::string const& argv0 = this->CommandLines[c][0];
  cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
  if (target && target->GetType() == cm::TargetType::EXECUTABLE &&
      (target->IsImported() ||
       target->GetProperty("CROSSCOMPILING_EMULATOR") ||
       !this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"))) {
    return target->GetLocation(this->CommandConfig).c_str();
  }
  return nullptr;
}

bool cmCustomCommandGenerator::HasOnlyEmptyCommandLines() const
{
  for (cmCustomCommandLine const& ccl : this->CommandLines) {
    for (std::string const& cl : ccl) {
      if (!cl.empty()) {
        return false;
      }
    }
  }
  return true;
}

std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
{
  std::vector<std::string> emulator = this->GetCrossCompilingEmulator(c);
  if (!emulator.empty()) {
    return emulator[0];
  }
  if (char const* location = this->GetArgv0Location(c)) {
    return std::string(location);
  }

  return this->CommandLines[c][0];
}

static std::string escapeForShellOldStyle(std::string const& str)
{
  std::string result;
#if defined(_WIN32) && !defined(__CYGWIN__)
  // if there are spaces
  std::string temp = str;
  if (temp.find(" ") != std::string::npos &&
      temp.find("\"") == std::string::npos) {
    result = cmStrCat('"', str, '"');
    return result;
  }
  return str;
#else
  for (char const* ch = str.c_str(); *ch != '\0'; ++ch) {
    if (*ch == ' ') {
      result += '\\';
    }
    result += *ch;
  }
  return result;
#endif
}

void cmCustomCommandGenerator::AppendArguments(unsigned int c,
                                               std::string& cmd) const
{
  unsigned int offset = 1;
  std::vector<std::string> emulator = this->GetCrossCompilingEmulator(c);
  if (!emulator.empty()) {
    for (unsigned j = 1; j < emulator.size(); ++j) {
      cmd += " ";
      if (this->OldStyle) {
        cmd += escapeForShellOldStyle(emulator[j]);
      } else {
        cmd +=
          this->LG->EscapeForShell(emulator[j], this->MakeVars, false, false,
                                   this->MakeVars && this->LG->IsNinjaMulti());
      }
    }

    offset = 0;
  }

  cmCustomCommandLine const& commandLine = this->CommandLines[c];
  for (unsigned int j = offset; j < commandLine.size(); ++j) {
    std::string arg;
    if (char const* location = j == 0 ? this->GetArgv0Location(c) : nullptr) {
      // GetCommand returned the emulator instead of the argv0 location,
      // so transform the latter now.
      arg = location;
    } else {
      arg = commandLine[j];
    }
    cmd += " ";
    if (this->OldStyle) {
      cmd += escapeForShellOldStyle(arg);
    } else {
      cmd +=
        this->LG->EscapeForShell(arg, this->MakeVars, false, false,
                                 this->MakeVars && this->LG->IsNinjaMulti());
    }
  }
}

std::string cmCustomCommandGenerator::GetDepfile() const
{
  auto const& depfile = this->CC->GetDepfile();
  if (depfile.empty()) {
    return "";
  }

  cmGeneratorExpression ge(*this->LG->GetCMakeInstance(),
                           this->CC->GetBacktrace());
  return EvaluateDepfile(depfile, ge, this->LG, this->OutputConfig);
}

std::string cmCustomCommandGenerator::GetFullDepfile() const
{
  std::string depfile = this->GetDepfile();
  if (depfile.empty()) {
    return "";
  }

  if (!cmSystemTools::FileIsFullPath(depfile)) {
    depfile = cmStrCat(this->LG->GetCurrentBinaryDirectory(), '/', depfile);
  }
  return cmSystemTools::CollapseFullPath(depfile);
}

std::string cmCustomCommandGenerator::GetInternalDepfileName(
  std::string const& /*config*/, std::string const& depfile) const
{
  cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
  std::string extension;
  switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) {
    case cmDepfileFormat::GccDepfile:
    case cmDepfileFormat::MakeDepfile:
      extension = ".d";
      break;
    case cmDepfileFormat::MSBuildAdditionalInputs:
      extension = ".AdditionalInputs";
      break;
  }
  return cmStrCat(this->LG->GetBinaryDirectory(), "/CMakeFiles/d/",
                  hash.HashString(depfile), extension);
}

std::string cmCustomCommandGenerator::GetInternalDepfile() const
{
  std::string depfile = this->GetFullDepfile();
  if (depfile.empty()) {
    return "";
  }

  if (this->ComputeInternalDepfile) {
    return this->ComputeInternalDepfile(this->OutputConfig, depfile);
  }
  return this->GetInternalDepfileName(this->OutputConfig, depfile);
}

cm::optional<std::string> cmCustomCommandGenerator::GetComment() const
{
  char const* comment = this->CC->GetComment();
  if (!comment) {
    return cm::nullopt;
  }
  if (!*comment) {
    return std::string();
  }

  cmGeneratorExpression ge(*this->LG->GetCMakeInstance(),
                           this->CC->GetBacktrace());
  return EvaluateComment(comment, ge, this->LG, this->OutputConfig);
}

std::string cmCustomCommandGenerator::GetWorkingDirectory() const
{
  return this->WorkingDirectory;
}

std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
{
  return this->Outputs;
}

std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const
{
  return this->Byproducts;
}

std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
{
  return this->Depends;
}

std::set<BT<std::pair<std::string, bool>>> const&
cmCustomCommandGenerator::GetUtilities() const
{
  return this->Utilities;
}
