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

#include <algorithm>
#include <functional>
#include <iomanip>
#include <map>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

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

#include "cmArgumentParser.h"
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmValue.h"

namespace {
// Helper classes for argument parsing
template <typename Result>
class CMakePathArgumentParser : public cmArgumentParser<Result>
{
public:
  CMakePathArgumentParser()
    : cmArgumentParser<Result>()
  {
  }

  template <typename T>
  CMakePathArgumentParser& Bind(cm::static_string_view name, T Result::*member)
  {
    this->cmArgumentParser<Result>::Bind(name, member);
    return *this;
  }

  template <int Advance = 2>
  Result Parse(std::vector<std::string> const& args,
               std::vector<std::string>* keywordsMissingValue = nullptr,
               std::vector<std::string>* parsedKeywords = nullptr) const
  {
    this->Inputs.clear();

    return this->cmArgumentParser<Result>::Parse(
      cmMakeRange(args).advance(Advance), &this->Inputs, keywordsMissingValue,
      parsedKeywords);
  }

  const std::vector<std::string>& GetInputs() const { return this->Inputs; }

protected:
  mutable std::vector<std::string> Inputs;
};

// OUTPUT_VARIABLE is expected
template <typename Result>
class ArgumentParserWithOutputVariable : public CMakePathArgumentParser<Result>
{
public:
  ArgumentParserWithOutputVariable()
    : CMakePathArgumentParser<Result>()
  {
    this->Bind("OUTPUT_VARIABLE"_s, &Result::Output);
  }

  template <typename T>
  ArgumentParserWithOutputVariable& Bind(cm::static_string_view name,
                                         T Result::*member)
  {
    this->cmArgumentParser<Result>::Bind(name, member);
    return *this;
  }

  template <int Advance = 2>
  Result Parse(std::vector<std::string> const& args) const
  {
    this->KeywordsMissingValue.clear();
    this->ParsedKeywords.clear();

    return this->CMakePathArgumentParser<Result>::template Parse<Advance>(
      args, &this->KeywordsMissingValue, &this->ParsedKeywords);
  }

  const std::vector<std::string>& GetKeywordsMissingValue() const
  {
    return this->KeywordsMissingValue;
  }
  const std::vector<std::string>& GetParsedKeywords() const
  {
    return this->ParsedKeywords;
  }

  bool checkOutputVariable(const Result& arguments,
                           cmExecutionStatus& status) const
  {
    if (std::find(this->GetKeywordsMissingValue().begin(),
                  this->GetKeywordsMissingValue().end(),
                  "OUTPUT_VARIABLE"_s) !=
        this->GetKeywordsMissingValue().end()) {
      status.SetError("OUTPUT_VARIABLE requires an argument.");
      return false;
    }

    if (std::find(this->GetParsedKeywords().begin(),
                  this->GetParsedKeywords().end(),
                  "OUTPUT_VARIABLE"_s) != this->GetParsedKeywords().end() &&
        arguments.Output.empty()) {
      status.SetError("Invalid name for output variable.");
      return false;
    }

    return true;
  }

private:
  mutable std::vector<std::string> KeywordsMissingValue;
  mutable std::vector<std::string> ParsedKeywords;
};

struct OutputVariable
{
  std::string Output;
};
// Usable when OUTPUT_VARIABLE is the only option
class OutputVariableParser
  : public ArgumentParserWithOutputVariable<OutputVariable>
{
};

struct NormalizeOption
{
  bool Normalize = false;
};
// Usable when NORMALIZE is the only option
class NormalizeParser : public CMakePathArgumentParser<NormalizeOption>
{
public:
  NormalizeParser() { this->Bind("NORMALIZE"_s, &NormalizeOption::Normalize); }
};

// retrieve value of input path from specified variable
bool getInputPath(const std::string& arg, cmExecutionStatus& status,
                  std::string& path)
{
  cmValue def = status.GetMakefile().GetDefinition(arg);
  if (!def) {
    status.SetError("undefined variable for input path.");
    return false;
  }

  path = *def;
  return true;
}

bool HandleGetCommand(std::vector<std::string> const& args,
                      cmExecutionStatus& status)
{
  static std::map<cm::string_view,
                  std::function<cmCMakePath(const cmCMakePath&, bool)>> const
    actions{ { "ROOT_NAME"_s,
               [](const cmCMakePath& path, bool) -> cmCMakePath {
                 return path.GetRootName();
               } },
             { "ROOT_DIRECTORY"_s,
               [](const cmCMakePath& path, bool) -> cmCMakePath {
                 return path.GetRootDirectory();
               } },
             { "ROOT_PATH"_s,
               [](const cmCMakePath& path, bool) -> cmCMakePath {
                 return path.GetRootPath();
               } },
             { "FILENAME"_s,
               [](const cmCMakePath& path, bool) -> cmCMakePath {
                 return path.GetFileName();
               } },
             { "EXTENSION"_s,
               [](const cmCMakePath& path, bool last_only) -> cmCMakePath {
                 if (last_only) {
                   return path.GetExtension();
                 }
                 return path.GetWideExtension();
               } },
             { "STEM"_s,
               [](const cmCMakePath& path, bool last_only) -> cmCMakePath {
                 if (last_only) {
                   return path.GetStem();
                 }
                 return path.GetNarrowStem();
               } },
             { "RELATIVE_PART"_s,
               [](const cmCMakePath& path, bool) -> cmCMakePath {
                 return path.GetRelativePath();
               } },
             { "PARENT_PATH"_s,
               [](const cmCMakePath& path, bool) -> cmCMakePath {
                 return path.GetParentPath();
               } } };

  if (args.size() < 4) {
    status.SetError("GET must be called with at least three arguments.");
    return false;
  }

  const auto& action = args[2];

  if (actions.find(action) == actions.end()) {
    status.SetError(
      cmStrCat("GET called with an unknown action: ", action, "."));
    return false;
  }

  struct Arguments
  {
    bool LastOnly = false;
  };

  CMakePathArgumentParser<Arguments> parser;
  if ((action == "EXTENSION"_s || action == "STEM"_s)) {
    parser.Bind("LAST_ONLY"_s, &Arguments::LastOnly);
  }

  Arguments const arguments = parser.Parse<3>(args);

  if (parser.GetInputs().size() != 1) {
    status.SetError("GET called with unexpected arguments.");
    return false;
  }
  if (parser.GetInputs().front().empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  std::string path;
  if (!getInputPath(args[1], status, path)) {
    return false;
  }

  auto result = actions.at(action)(path, arguments.LastOnly);

  status.GetMakefile().AddDefinition(parser.GetInputs().front(),
                                     result.String());

  return true;
}

bool HandleSetCommand(std::vector<std::string> const& args,
                      cmExecutionStatus& status)
{
  if (args.size() < 3 || args.size() > 4) {
    status.SetError("SET must be called with two or three arguments.");
    return false;
  }

  if (args[1].empty()) {
    status.SetError("Invalid name for path variable.");
    return false;
  }

  static NormalizeParser const parser;

  const auto arguments = parser.Parse(args);

  if (parser.GetInputs().size() != 1) {
    status.SetError("SET called with unexpected arguments.");
    return false;
  }

  auto path =
    cmCMakePath(parser.GetInputs().front(), cmCMakePath::native_format);

  if (arguments.Normalize) {
    path = path.Normal();
  }

  status.GetMakefile().AddDefinition(args[1], path.GenericString());

  return true;
}

bool HandleAppendCommand(std::vector<std::string> const& args,
                         cmExecutionStatus& status)
{
  if (args[1].empty()) {
    status.SetError("Invalid name for path variable.");
    return false;
  }

  static OutputVariableParser const parser{};

  const auto arguments = parser.Parse(args);

  if (!parser.checkOutputVariable(arguments, status)) {
    return false;
  }

  cmCMakePath path(status.GetMakefile().GetSafeDefinition(args[1]));
  for (const auto& input : parser.GetInputs()) {
    path /= input;
  }

  status.GetMakefile().AddDefinition(
    arguments.Output.empty() ? args[1] : arguments.Output, path.String());

  return true;
}

bool HandleAppendStringCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  static OutputVariableParser const parser{};

  const auto arguments = parser.Parse(args);

  if (!parser.checkOutputVariable(arguments, status)) {
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  for (const auto& input : parser.GetInputs()) {
    path += input;
  }

  status.GetMakefile().AddDefinition(
    arguments.Output.empty() ? args[1] : arguments.Output, path.String());

  return true;
}

bool HandleRemoveFilenameCommand(std::vector<std::string> const& args,
                                 cmExecutionStatus& status)
{
  static OutputVariableParser const parser{};

  const auto arguments = parser.Parse(args);

  if (!parser.checkOutputVariable(arguments, status)) {
    return false;
  }

  if (!parser.GetInputs().empty()) {
    status.SetError("REMOVE_FILENAME called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  path.RemoveFileName();

  status.GetMakefile().AddDefinition(
    arguments.Output.empty() ? args[1] : arguments.Output, path.String());

  return true;
}

bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
{
  static OutputVariableParser const parser{};

  const auto arguments = parser.Parse(args);

  if (!parser.checkOutputVariable(arguments, status)) {
    return false;
  }

  if (parser.GetInputs().size() > 1) {
    status.SetError("REPLACE_FILENAME called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  path.ReplaceFileName(
    parser.GetInputs().empty() ? "" : parser.GetInputs().front());

  status.GetMakefile().AddDefinition(
    arguments.Output.empty() ? args[1] : arguments.Output, path.String());

  return true;
}

bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
{
  struct Arguments
  {
    std::string Output;
    bool LastOnly = false;
  };

  static auto const parser =
    ArgumentParserWithOutputVariable<Arguments>{}.Bind("LAST_ONLY"_s,
                                                       &Arguments::LastOnly);

  Arguments const arguments = parser.Parse(args);

  if (!parser.checkOutputVariable(arguments, status)) {
    return false;
  }

  if (!parser.GetInputs().empty()) {
    status.SetError("REMOVE_EXTENSION called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);

  if (arguments.LastOnly) {
    path.RemoveExtension();
  } else {
    path.RemoveWideExtension();
  }

  status.GetMakefile().AddDefinition(
    arguments.Output.empty() ? args[1] : arguments.Output, path.String());

  return true;
}

bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
                                   cmExecutionStatus& status)
{
  struct Arguments
  {
    std::string Output;
    bool LastOnly = false;
  };

  static auto const parser =
    ArgumentParserWithOutputVariable<Arguments>{}.Bind("LAST_ONLY"_s,
                                                       &Arguments::LastOnly);

  Arguments const arguments = parser.Parse(args);

  if (!parser.checkOutputVariable(arguments, status)) {
    return false;
  }

  if (parser.GetInputs().size() > 1) {
    status.SetError("REPLACE_EXTENSION called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  cmCMakePath extension(
    parser.GetInputs().empty() ? "" : parser.GetInputs().front());

  if (arguments.LastOnly) {
    path.ReplaceExtension(extension);
  } else {
    path.ReplaceWideExtension(extension);
  }

  status.GetMakefile().AddDefinition(
    arguments.Output.empty() ? args[1] : arguments.Output, path.String());

  return true;
}

bool HandleNormalPathCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  static OutputVariableParser const parser{};

  const auto arguments = parser.Parse(args);

  if (!parser.checkOutputVariable(arguments, status)) {
    return false;
  }

  if (!parser.GetInputs().empty()) {
    status.SetError("NORMAL_PATH called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  auto path = cmCMakePath(inputPath).Normal();

  status.GetMakefile().AddDefinition(
    arguments.Output.empty() ? args[1] : arguments.Output, path.String());

  return true;
}

bool HandleTransformPathCommand(
  std::vector<std::string> const& args, cmExecutionStatus& status,
  const std::function<cmCMakePath(const cmCMakePath&,
                                  const std::string& base)>& transform,
  bool normalizeOption = false)
{
  struct Arguments
  {
    std::string Output;
    std::string BaseDirectory;
    bool Normalize = false;
  };

  auto parser = ArgumentParserWithOutputVariable<Arguments>{}.Bind(
    "BASE_DIRECTORY"_s, &Arguments::BaseDirectory);
  if (normalizeOption) {
    parser.Bind("NORMALIZE"_s, &Arguments::Normalize);
  }

  Arguments arguments = parser.Parse(args);

  if (!parser.checkOutputVariable(arguments, status)) {
    return false;
  }

  if (!parser.GetInputs().empty()) {
    status.SetError(cmStrCat(args[0], " called with unexpected arguments."));
    return false;
  }

  if (std::find(parser.GetKeywordsMissingValue().begin(),
                parser.GetKeywordsMissingValue().end(), "BASE_DIRECTORY"_s) !=
      parser.GetKeywordsMissingValue().end()) {
    status.SetError("BASE_DIRECTORY requires an argument.");
    return false;
  }

  if (std::find(parser.GetParsedKeywords().begin(),
                parser.GetParsedKeywords().end(),
                "BASE_DIRECTORY"_s) == parser.GetParsedKeywords().end()) {
    arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  auto path = transform(cmCMakePath(inputPath), arguments.BaseDirectory);
  if (arguments.Normalize) {
    path = path.Normal();
  }

  status.GetMakefile().AddDefinition(
    arguments.Output.empty() ? args[1] : arguments.Output, path.String());

  return true;
}

bool HandleRelativePathCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  return HandleTransformPathCommand(
    args, status,
    [](const cmCMakePath& path, const std::string& base) -> cmCMakePath {
      return path.Relative(base);
    });
}

bool HandleAbsolutePathCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  return HandleTransformPathCommand(
    args, status,
    [](const cmCMakePath& path, const std::string& base) -> cmCMakePath {
      return path.Absolute(base);
    },
    true);
}

bool HandleNativePathCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  if (args.size() < 3 || args.size() > 4) {
    status.SetError("NATIVE_PATH must be called with two or three arguments.");
    return false;
  }

  static NormalizeParser const parser;

  const auto arguments = parser.Parse(args);

  if (parser.GetInputs().size() != 1) {
    status.SetError("NATIVE_PATH called with unexpected arguments.");
    return false;
  }
  if (parser.GetInputs().front().empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  cmCMakePath path(inputPath);
  if (arguments.Normalize) {
    path = path.Normal();
  }

  status.GetMakefile().AddDefinition(parser.GetInputs().front(),
                                     path.NativeString());

  return true;
}

bool HandleConvertCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
  const auto pathSep = ";"_s;
#else
  const auto pathSep = ":"_s;
#endif
  const auto cmakePath = "TO_CMAKE_PATH_LIST"_s;
  const auto nativePath = "TO_NATIVE_PATH_LIST"_s;

  if (args.size() < 4 || args.size() > 5) {
    status.SetError("CONVERT must be called with three or four arguments.");
    return false;
  }

  const auto& action = args[2];

  if (action != cmakePath && action != nativePath) {
    status.SetError(
      cmStrCat("CONVERT called with an unknown action: ", action, "."));
    return false;
  }

  if (args[3].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  static NormalizeParser const parser;

  const auto arguments = parser.Parse<4>(args);

  if (!parser.GetInputs().empty()) {
    status.SetError("CONVERT called with unexpected arguments.");
    return false;
  }

  std::vector<std::string> paths;

  if (action == cmakePath) {
    paths = cmSystemTools::SplitString(args[1], pathSep.front());
  } else {
    cmExpandList(args[1], paths);
  }

  for (auto& path : paths) {
    auto p = cmCMakePath(path,
                         action == cmakePath ? cmCMakePath::native_format
                                             : cmCMakePath::generic_format);
    if (arguments.Normalize) {
      p = p.Normal();
    }
    if (action == cmakePath) {
      path = p.GenericString();
    } else {
      path = p.NativeString();
    }
  }

  auto value = cmJoin(paths, action == cmakePath ? ";"_s : pathSep);
  status.GetMakefile().AddDefinition(args[3], value);

  return true;
}

bool HandleCompareCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  if (args.size() != 5) {
    status.SetError("COMPARE must be called with four arguments.");
    return false;
  }

  static std::map<cm::string_view,
                  std::function<bool(const cmCMakePath&,
                                     const cmCMakePath&)>> const operators{
    { "EQUAL"_s,
      [](const cmCMakePath& path1, const cmCMakePath& path2) -> bool {
        return path1 == path2;
      } },
    { "NOT_EQUAL"_s,
      [](const cmCMakePath& path1, const cmCMakePath& path2) -> bool {
        return path1 != path2;
      } }
  };

  const auto op = operators.find(args[2]);
  if (op == operators.end()) {
    status.SetError(cmStrCat(
      "COMPARE called with an unknown comparison operator: ", args[2], "."));
    return false;
  }

  if (args[4].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  cmCMakePath path1(args[1]);
  cmCMakePath path2(args[3]);
  auto result = op->second(path1, path2);

  status.GetMakefile().AddDefinitionBool(args[4], result);

  return true;
}

bool HandleHasItemCommand(
  std::vector<std::string> const& args, cmExecutionStatus& status,
  const std::function<bool(const cmCMakePath&)>& has_item)
{
  if (args.size() != 3) {
    status.SetError(
      cmStrCat(args.front(), " must be called with two arguments."));
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  if (args[2].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  cmCMakePath path(inputPath);
  auto result = has_item(path);

  status.GetMakefile().AddDefinitionBool(args[2], result);

  return true;
}

bool HandleHasRootNameCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](const cmCMakePath& path) -> bool { return path.HasRootName(); });
}

bool HandleHasRootDirectoryCommand(std::vector<std::string> const& args,
                                   cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](const cmCMakePath& path) -> bool { return path.HasRootDirectory(); });
}

bool HandleHasRootPathCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](const cmCMakePath& path) -> bool { return path.HasRootPath(); });
}

bool HandleHasFilenameCommand(std::vector<std::string> const& args,
                              cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](const cmCMakePath& path) -> bool { return path.HasFileName(); });
}

bool HandleHasExtensionCommand(std::vector<std::string> const& args,
                               cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](const cmCMakePath& path) -> bool { return path.HasExtension(); });
}

bool HandleHasStemCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](const cmCMakePath& path) -> bool { return path.HasStem(); });
}

bool HandleHasRelativePartCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](const cmCMakePath& path) -> bool { return path.HasRelativePath(); });
}

bool HandleHasParentPathCommand(std::vector<std::string> const& args,
                                cmExecutionStatus& status)
{
  return HandleHasItemCommand(
    args, status,
    [](const cmCMakePath& path) -> bool { return path.HasParentPath(); });
}

bool HandleIsAbsoluteCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  if (args.size() != 3) {
    status.SetError("IS_ABSOLUTE must be called with two arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  if (args[2].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  bool isAbsolute = cmCMakePath(inputPath).IsAbsolute();

  status.GetMakefile().AddDefinitionBool(args[2], isAbsolute);

  return true;
}

bool HandleIsRelativeCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
{
  if (args.size() != 3) {
    status.SetError("IS_RELATIVE must be called with two arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  if (args[2].empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  bool isRelative = cmCMakePath(inputPath).IsRelative();

  status.GetMakefile().AddDefinitionBool(args[2], isRelative);

  return true;
}

bool HandleIsPrefixCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
  if (args.size() < 4 || args.size() > 5) {
    status.SetError("IS_PREFIX must be called with three or four arguments.");
    return false;
  }

  static NormalizeParser const parser;

  const auto arguments = parser.Parse(args);

  if (parser.GetInputs().size() != 2) {
    status.SetError("IS_PREFIX called with unexpected arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  const auto& input = parser.GetInputs().front();
  const auto& output = parser.GetInputs().back();

  if (output.empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  bool isPrefix;
  if (arguments.Normalize) {
    isPrefix =
      cmCMakePath(inputPath).Normal().IsPrefix(cmCMakePath(input).Normal());
  } else {
    isPrefix = cmCMakePath(inputPath).IsPrefix(input);
  }

  status.GetMakefile().AddDefinitionBool(output, isPrefix);

  return true;
}

bool HandleHashCommand(std::vector<std::string> const& args,
                       cmExecutionStatus& status)
{
  if (args.size() != 3) {
    status.SetError("HASH must be called with two arguments.");
    return false;
  }

  std::string inputPath;
  if (!getInputPath(args[1], status, inputPath)) {
    return false;
  }

  const auto& output = args[2];

  if (output.empty()) {
    status.SetError("Invalid name for output variable.");
    return false;
  }

  auto hash = hash_value(cmCMakePath(inputPath).Normal());

  std::ostringstream out;
  out << std::setbase(16) << hash;

  status.GetMakefile().AddDefinition(output, out.str());

  return true;
}
} // anonymous namespace

bool cmCMakePathCommand(std::vector<std::string> const& args,
                        cmExecutionStatus& status)
{
  if (args.size() < 2) {
    status.SetError("must be called with at least two arguments.");
    return false;
  }

  static cmSubcommandTable const subcommand{
    { "GET"_s, HandleGetCommand },
    { "SET"_s, HandleSetCommand },
    { "APPEND"_s, HandleAppendCommand },
    { "APPEND_STRING"_s, HandleAppendStringCommand },
    { "REMOVE_FILENAME"_s, HandleRemoveFilenameCommand },
    { "REPLACE_FILENAME"_s, HandleReplaceFilenameCommand },
    { "REMOVE_EXTENSION"_s, HandleRemoveExtensionCommand },
    { "REPLACE_EXTENSION"_s, HandleReplaceExtensionCommand },
    { "NORMAL_PATH"_s, HandleNormalPathCommand },
    { "RELATIVE_PATH"_s, HandleRelativePathCommand },
    { "ABSOLUTE_PATH"_s, HandleAbsolutePathCommand },
    { "NATIVE_PATH"_s, HandleNativePathCommand },
    { "CONVERT"_s, HandleConvertCommand },
    { "COMPARE"_s, HandleCompareCommand },
    { "HAS_ROOT_NAME"_s, HandleHasRootNameCommand },
    { "HAS_ROOT_DIRECTORY"_s, HandleHasRootDirectoryCommand },
    { "HAS_ROOT_PATH"_s, HandleHasRootPathCommand },
    { "HAS_FILENAME"_s, HandleHasFilenameCommand },
    { "HAS_EXTENSION"_s, HandleHasExtensionCommand },
    { "HAS_STEM"_s, HandleHasStemCommand },
    { "HAS_RELATIVE_PART"_s, HandleHasRelativePartCommand },
    { "HAS_PARENT_PATH"_s, HandleHasParentPathCommand },
    { "IS_ABSOLUTE"_s, HandleIsAbsoluteCommand },
    { "IS_RELATIVE"_s, HandleIsRelativeCommand },
    { "IS_PREFIX"_s, HandleIsPrefixCommand },
    { "HASH"_s, HandleHashCommand }
  };

  return subcommand(args[0], args, status);
}
