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

#include <set>
#include <sstream>

#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmInstalledFile.h"
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTest.h"
#include "cmake.h"

namespace {
bool HandleGlobalMode(cmExecutionStatus& status,
                      const std::set<std::string>& names,
                      const std::string& propertyName,
                      const std::string& propertyValue, bool appendAsString,
                      bool appendMode, bool remove);
bool HandleDirectoryMode(cmExecutionStatus& status,
                         const std::set<std::string>& names,
                         const std::string& propertyName,
                         const std::string& propertyValue, bool appendAsString,
                         bool appendMode, bool remove);
bool HandleTargetMode(cmExecutionStatus& status,
                      const std::set<std::string>& names,
                      const std::string& propertyName,
                      const std::string& propertyValue, bool appendAsString,
                      bool appendMode, bool remove);
bool HandleTarget(cmTarget* target, cmMakefile& makefile,
                  const std::string& propertyName,
                  const std::string& propertyValue, bool appendAsString,
                  bool appendMode, bool remove);
bool HandleSourceMode(cmExecutionStatus& status,
                      const std::set<std::string>& names,
                      const std::string& propertyName,
                      const std::string& propertyValue, bool appendAsString,
                      bool appendMode, bool remove,
                      const std::vector<cmMakefile*>& directory_makefiles,
                      bool source_file_paths_should_be_absolute);
bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
                  const std::string& propertyValue, bool appendAsString,
                  bool appendMode, bool remove);
bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
                    const std::string& propertyName,
                    const std::string& propertyValue, bool appendAsString,
                    bool appendMode, bool remove);
bool HandleTest(cmTest* test, const std::string& propertyName,
                const std::string& propertyValue, bool appendAsString,
                bool appendMode, bool remove);
bool HandleCacheMode(cmExecutionStatus& status,
                     const std::set<std::string>& names,
                     const std::string& propertyName,
                     const std::string& propertyValue, bool appendAsString,
                     bool appendMode, bool remove);
bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
                      const std::string& propertyName,
                      const std::string& propertyValue, bool appendAsString,
                      bool appendMode, bool remove);
bool HandleInstallMode(cmExecutionStatus& status,
                       const std::set<std::string>& names,
                       const std::string& propertyName,
                       const std::string& propertyValue, bool appendAsString,
                       bool appendMode, bool remove);
bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
                   const std::string& propertyName,
                   const std::string& propertyValue, bool appendAsString,
                   bool appendMode, bool remove);
}

namespace SetPropertyCommand {
bool HandleSourceFileDirectoryScopes(
  cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
  std::vector<std::string>& source_file_target_directories,
  std::vector<cmMakefile*>& directory_makefiles)
{
  cmMakefile* current_dir_mf = &status.GetMakefile();
  if (!source_file_directories.empty()) {
    for (const std::string& dir_path : source_file_directories) {
      const std::string absolute_dir_path = cmSystemTools::CollapseFullPath(
        dir_path, current_dir_mf->GetCurrentSourceDirectory());
      cmMakefile* dir_mf =
        status.GetMakefile().GetGlobalGenerator()->FindMakefile(
          absolute_dir_path);
      if (!dir_mf) {
        status.SetError(cmStrCat("given non-existent DIRECTORY ", dir_path));
        return false;
      }
      directory_makefiles.push_back(dir_mf);
    }
  } else if (!source_file_target_directories.empty()) {
    for (const std::string& target_name : source_file_target_directories) {
      cmTarget* target = current_dir_mf->FindTargetToUse(target_name);
      if (!target) {
        status.SetError(cmStrCat(
          "given non-existent target for DIRECTORY_TARGET ", target_name));
        return false;
      }
      cmProp target_source_dir = target->GetProperty("SOURCE_DIR");
      cmMakefile* target_dir_mf =
        status.GetMakefile().GetGlobalGenerator()->FindMakefile(
          *target_source_dir);
      directory_makefiles.push_back(target_dir_mf);
    }
  } else {
    directory_makefiles.push_back(current_dir_mf);
  }
  return true;
}

bool HandleSourceFileDirectoryScopeValidation(
  cmExecutionStatus& status, bool source_file_directory_option_enabled,
  bool source_file_target_option_enabled,
  std::vector<std::string>& source_file_directories,
  std::vector<std::string>& source_file_target_directories)
{
  // Validate source file directory scopes.
  if (source_file_directory_option_enabled &&
      source_file_directories.empty()) {
    std::string errors = "called with incorrect number of arguments "
                         "no value provided to the DIRECTORY option";
    status.SetError(errors);
    return false;
  }
  if (source_file_target_option_enabled &&
      source_file_target_directories.empty()) {
    std::string errors = "called with incorrect number of arguments "
                         "no value provided to the TARGET_DIRECTORY option";
    status.SetError(errors);
    return false;
  }
  return true;
}

bool HandleAndValidateSourceFileDirectortoryScopes(
  cmExecutionStatus& status, bool source_file_directory_option_enabled,
  bool source_file_target_option_enabled,
  std::vector<std::string>& source_file_directories,
  std::vector<std::string>& source_file_target_directories,
  std::vector<cmMakefile*>& source_file_directory_makefiles)
{
  bool scope_options_valid =
    SetPropertyCommand::HandleSourceFileDirectoryScopeValidation(
      status, source_file_directory_option_enabled,
      source_file_target_option_enabled, source_file_directories,
      source_file_target_directories);
  if (!scope_options_valid) {
    return false;
  }

  scope_options_valid = SetPropertyCommand::HandleSourceFileDirectoryScopes(
    status, source_file_directories, source_file_target_directories,
    source_file_directory_makefiles);
  return scope_options_valid;
}

std::string MakeSourceFilePathAbsoluteIfNeeded(
  cmExecutionStatus& status, const std::string& source_file_path,
  const bool needed)
{
  if (!needed) {
    return source_file_path;
  }
  const std::string absolute_file_path = cmSystemTools::CollapseFullPath(
    source_file_path, status.GetMakefile().GetCurrentSourceDirectory());
  return absolute_file_path;
}

void MakeSourceFilePathsAbsoluteIfNeeded(
  cmExecutionStatus& status,
  std::vector<std::string>& source_files_absolute_paths,
  std::vector<std::string>::const_iterator files_it_begin,
  std::vector<std::string>::const_iterator files_it_end, const bool needed)
{

  // Make the file paths absolute, so that relative source file paths are
  // picked up relative to the command calling site, regardless of the
  // directory scope.
  std::vector<std::string>::difference_type num_files =
    files_it_end - files_it_begin;
  source_files_absolute_paths.reserve(num_files);

  if (!needed) {
    source_files_absolute_paths.assign(files_it_begin, files_it_end);
    return;
  }

  for (; files_it_begin != files_it_end; ++files_it_begin) {
    const std::string absolute_file_path =
      MakeSourceFilePathAbsoluteIfNeeded(status, *files_it_begin, true);
    source_files_absolute_paths.push_back(absolute_file_path);
  }
}
}

bool cmSetPropertyCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  if (args.size() < 2) {
    status.SetError("called with incorrect number of arguments");
    return false;
  }

  // Get the scope on which to set the property.
  std::string const& scopeName = args.front();
  cmProperty::ScopeType scope;
  if (scopeName == "GLOBAL") {
    scope = cmProperty::GLOBAL;
  } else if (scopeName == "DIRECTORY") {
    scope = cmProperty::DIRECTORY;
  } else if (scopeName == "TARGET") {
    scope = cmProperty::TARGET;
  } else if (scopeName == "SOURCE") {
    scope = cmProperty::SOURCE_FILE;
  } else if (scopeName == "TEST") {
    scope = cmProperty::TEST;
  } else if (scopeName == "CACHE") {
    scope = cmProperty::CACHE;
  } else if (scopeName == "INSTALL") {
    scope = cmProperty::INSTALL;
  } else {
    status.SetError(cmStrCat("given invalid scope ", scopeName,
                             ".  "
                             "Valid scopes are GLOBAL, DIRECTORY, "
                             "TARGET, SOURCE, TEST, CACHE, INSTALL."));
    return false;
  }

  bool appendAsString = false;
  bool appendMode = false;
  bool remove = true;
  std::set<std::string> names;
  std::string propertyName;
  std::string propertyValue;

  std::vector<std::string> source_file_directories;
  std::vector<std::string> source_file_target_directories;
  bool source_file_directory_option_enabled = false;
  bool source_file_target_option_enabled = false;

  // Parse the rest of the arguments up to the values.
  enum Doing
  {
    DoingNone,
    DoingNames,
    DoingProperty,
    DoingValues,
    DoingSourceDirectory,
    DoingSourceTargetDirectory
  };
  Doing doing = DoingNames;
  const char* sep = "";
  for (std::string const& arg : cmMakeRange(args).advance(1)) {
    if (arg == "PROPERTY") {
      doing = DoingProperty;
    } else if (arg == "APPEND") {
      doing = DoingNone;
      appendMode = true;
      remove = false;
      appendAsString = false;
    } else if (arg == "APPEND_STRING") {
      doing = DoingNone;
      appendMode = true;
      remove = false;
      appendAsString = true;
    } else if (doing == DoingNames && scope == cmProperty::SOURCE_FILE &&
               arg == "DIRECTORY") {
      doing = DoingSourceDirectory;
      source_file_directory_option_enabled = true;
    } else if (doing == DoingNames && scope == cmProperty::SOURCE_FILE &&
               arg == "TARGET_DIRECTORY") {
      doing = DoingSourceTargetDirectory;
      source_file_target_option_enabled = true;
    } else if (doing == DoingNames) {
      names.insert(arg);
    } else if (doing == DoingSourceDirectory) {
      source_file_directories.push_back(arg);
    } else if (doing == DoingSourceTargetDirectory) {
      source_file_target_directories.push_back(arg);
    } else if (doing == DoingProperty) {
      propertyName = arg;
      doing = DoingValues;
    } else if (doing == DoingValues) {
      propertyValue += sep;
      sep = ";";
      propertyValue += arg;
      remove = false;
    } else {
      status.SetError(cmStrCat("given invalid argument \"", arg, "\"."));
      return false;
    }
  }

  // Make sure a property name was found.
  if (propertyName.empty()) {
    status.SetError("not given a PROPERTY <name> argument.");
    return false;
  }

  std::vector<cmMakefile*> source_file_directory_makefiles;
  bool file_scopes_handled =
    SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
      status, source_file_directory_option_enabled,
      source_file_target_option_enabled, source_file_directories,
      source_file_target_directories, source_file_directory_makefiles);
  if (!file_scopes_handled) {
    return false;
  }
  bool source_file_paths_should_be_absolute =
    source_file_directory_option_enabled || source_file_target_option_enabled;

  // Dispatch property setting.
  switch (scope) {
    case cmProperty::GLOBAL:
      return HandleGlobalMode(status, names, propertyName, propertyValue,
                              appendAsString, appendMode, remove);
    case cmProperty::DIRECTORY:
      return HandleDirectoryMode(status, names, propertyName, propertyValue,
                                 appendAsString, appendMode, remove);
    case cmProperty::TARGET:
      return HandleTargetMode(status, names, propertyName, propertyValue,
                              appendAsString, appendMode, remove);
    case cmProperty::SOURCE_FILE:
      return HandleSourceMode(status, names, propertyName, propertyValue,
                              appendAsString, appendMode, remove,
                              source_file_directory_makefiles,
                              source_file_paths_should_be_absolute);
    case cmProperty::TEST:
      return HandleTestMode(status, names, propertyName, propertyValue,
                            appendAsString, appendMode, remove);
    case cmProperty::CACHE:
      return HandleCacheMode(status, names, propertyName, propertyValue,
                             appendAsString, appendMode, remove);
    case cmProperty::INSTALL:
      return HandleInstallMode(status, names, propertyName, propertyValue,
                               appendAsString, appendMode, remove);

    case cmProperty::VARIABLE:
    case cmProperty::CACHED_VARIABLE:
      break; // should never happen
  }
  return true;
}

namespace {
bool HandleGlobalMode(cmExecutionStatus& status,
                      const std::set<std::string>& names,
                      const std::string& propertyName,
                      const std::string& propertyValue, bool appendAsString,
                      bool appendMode, bool remove)
{
  if (!names.empty()) {
    status.SetError("given names for GLOBAL scope.");
    return false;
  }

  // Set or append the property.
  cmake* cm = status.GetMakefile().GetCMakeInstance();
  if (appendMode) {
    cm->AppendProperty(propertyName, propertyValue, appendAsString);
  } else {
    if (remove) {
      cm->SetProperty(propertyName, nullptr);
    } else {
      cm->SetProperty(propertyName, propertyValue.c_str());
    }
  }

  return true;
}

bool HandleDirectoryMode(cmExecutionStatus& status,
                         const std::set<std::string>& names,
                         const std::string& propertyName,
                         const std::string& propertyValue, bool appendAsString,
                         bool appendMode, bool remove)
{
  if (names.size() > 1) {
    status.SetError("allows at most one name for DIRECTORY scope.");
    return false;
  }

  // Default to the current directory.
  cmMakefile* mf = &status.GetMakefile();

  // Lookup the directory if given.
  if (!names.empty()) {
    // Construct the directory name.  Interpret relative paths with
    // respect to the current directory.
    std::string dir = cmSystemTools::CollapseFullPath(
      *names.begin(), status.GetMakefile().GetCurrentSourceDirectory());

    mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
    if (!mf) {
      // Could not find the directory.
      status.SetError(
        "DIRECTORY scope provided but requested directory was not found. "
        "This could be because the directory argument was invalid or, "
        "it is valid but has not been processed yet.");
      return false;
    }
  }

  // Set or append the property.
  if (appendMode) {
    mf->AppendProperty(propertyName, propertyValue, appendAsString);
  } else {
    if (remove) {
      mf->SetProperty(propertyName, nullptr);
    } else {
      mf->SetProperty(propertyName, propertyValue.c_str());
    }
  }

  return true;
}

bool HandleTargetMode(cmExecutionStatus& status,
                      const std::set<std::string>& names,
                      const std::string& propertyName,
                      const std::string& propertyValue, bool appendAsString,
                      bool appendMode, bool remove)
{
  for (std::string const& name : names) {
    if (status.GetMakefile().IsAlias(name)) {
      status.SetError("can not be used on an ALIAS target.");
      return false;
    }
    if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
      // Handle the current target.
      if (!HandleTarget(target, status.GetMakefile(), propertyName,
                        propertyValue, appendAsString, appendMode, remove)) {
        return false;
      }
    } else {
      status.SetError(cmStrCat("could not find TARGET ", name,
                               ".  Perhaps it has not yet been created."));
      return false;
    }
  }
  return true;
}

bool HandleTarget(cmTarget* target, cmMakefile& makefile,
                  const std::string& propertyName,
                  const std::string& propertyValue, bool appendAsString,
                  bool appendMode, bool remove)
{
  // Set or append the property.
  if (appendMode) {
    target->AppendProperty(propertyName, propertyValue, appendAsString);
  } else {
    if (remove) {
      target->SetProperty(propertyName, nullptr);
    } else {
      target->SetProperty(propertyName, propertyValue);
    }
  }

  // Check the resulting value.
  target->CheckProperty(propertyName, &makefile);

  return true;
}

bool HandleSourceMode(cmExecutionStatus& status,
                      const std::set<std::string>& names,
                      const std::string& propertyName,
                      const std::string& propertyValue, bool appendAsString,
                      bool appendMode, bool remove,
                      const std::vector<cmMakefile*>& directory_makefiles,
                      const bool source_file_paths_should_be_absolute)
{
  std::vector<std::string> files_absolute;
  std::vector<std::string> unique_files(names.begin(), names.end());
  SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded(
    status, files_absolute, unique_files.begin(), unique_files.end(),
    source_file_paths_should_be_absolute);

  for (const auto mf : directory_makefiles) {
    for (std::string const& name : files_absolute) {
      // Get the source file.
      if (cmSourceFile* sf = mf->GetOrCreateSource(name)) {
        if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
                          appendMode, remove)) {
          return false;
        }
      } else {
        status.SetError(cmStrCat(
          "given SOURCE name that could not be found or created: ", name));
        return false;
      }
    }
  }

  return true;
}

bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
                  const std::string& propertyValue, bool appendAsString,
                  bool appendMode, bool remove)
{
  // Set or append the property.
  if (appendMode) {
    sf->AppendProperty(propertyName, propertyValue, appendAsString);
  } else {
    if (remove) {
      sf->SetProperty(propertyName, nullptr);
    } else {
      sf->SetProperty(propertyName, propertyValue.c_str());
    }
  }
  return true;
}

bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
                    const std::string& propertyName,
                    const std::string& propertyValue, bool appendAsString,
                    bool appendMode, bool remove)
{
  // Look for tests with all names given.
  std::set<std::string>::iterator next;
  for (auto ni = names.begin(); ni != names.end(); ni = next) {
    next = ni;
    ++next;
    if (cmTest* test = status.GetMakefile().GetTest(*ni)) {
      if (HandleTest(test, propertyName, propertyValue, appendAsString,
                     appendMode, remove)) {
        names.erase(ni);
      } else {
        return false;
      }
    }
  }

  // Names that are still left were not found.
  if (!names.empty()) {
    std::ostringstream e;
    e << "given TEST names that do not exist:\n";
    for (std::string const& name : names) {
      e << "  " << name << "\n";
    }
    status.SetError(e.str());
    return false;
  }
  return true;
}

bool HandleTest(cmTest* test, const std::string& propertyName,
                const std::string& propertyValue, bool appendAsString,
                bool appendMode, bool remove)
{
  // Set or append the property.
  if (appendMode) {
    test->AppendProperty(propertyName, propertyValue, appendAsString);
  } else {
    if (remove) {
      test->SetProperty(propertyName, nullptr);
    } else {
      test->SetProperty(propertyName, propertyValue.c_str());
    }
  }

  return true;
}

bool HandleCacheMode(cmExecutionStatus& status,
                     const std::set<std::string>& names,
                     const std::string& propertyName,
                     const std::string& propertyValue, bool appendAsString,
                     bool appendMode, bool remove)
{
  if (propertyName == "ADVANCED") {
    if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) {
      status.SetError(cmStrCat("given non-boolean value \"", propertyValue,
                               R"(" for CACHE property "ADVANCED".  )"));
      return false;
    }
  } else if (propertyName == "TYPE") {
    if (!cmState::IsCacheEntryType(propertyValue)) {
      status.SetError(
        cmStrCat("given invalid CACHE entry TYPE \"", propertyValue, "\""));
      return false;
    }
  } else if (propertyName != "HELPSTRING" && propertyName != "STRINGS" &&
             propertyName != "VALUE") {
    status.SetError(
      cmStrCat("given invalid CACHE property ", propertyName,
               ".  "
               "Settable CACHE properties are: "
               "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE."));
    return false;
  }

  for (std::string const& name : names) {
    // Get the source file.
    cmake* cm = status.GetMakefile().GetCMakeInstance();
    cmProp existingValue = cm->GetState()->GetCacheEntryValue(name);
    if (existingValue) {
      if (!HandleCacheEntry(name, status.GetMakefile(), propertyName,
                            propertyValue, appendAsString, appendMode,
                            remove)) {
        return false;
      }
    } else {
      status.SetError(cmStrCat("could not find CACHE variable ", name,
                               ".  Perhaps it has not yet been created."));
      return false;
    }
  }
  return true;
}

bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
                      const std::string& propertyName,
                      const std::string& propertyValue, bool appendAsString,
                      bool appendMode, bool remove)
{
  // Set or append the property.
  cmState* state = makefile.GetState();
  if (remove) {
    state->RemoveCacheEntryProperty(cacheKey, propertyName);
  }
  if (appendMode) {
    state->AppendCacheEntryProperty(cacheKey, propertyName, propertyValue,
                                    appendAsString);
  } else {
    state->SetCacheEntryProperty(cacheKey, propertyName, propertyValue);
  }

  return true;
}

bool HandleInstallMode(cmExecutionStatus& status,
                       const std::set<std::string>& names,
                       const std::string& propertyName,
                       const std::string& propertyValue, bool appendAsString,
                       bool appendMode, bool remove)
{
  cmake* cm = status.GetMakefile().GetCMakeInstance();

  for (std::string const& name : names) {
    if (cmInstalledFile* file =
          cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) {
      if (!HandleInstall(file, status.GetMakefile(), propertyName,
                         propertyValue, appendAsString, appendMode, remove)) {
        return false;
      }
    } else {
      status.SetError(cmStrCat(
        "given INSTALL name that could not be found or created: ", name));
      return false;
    }
  }
  return true;
}

bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
                   const std::string& propertyName,
                   const std::string& propertyValue, bool appendAsString,
                   bool appendMode, bool remove)
{
  // Set or append the property.
  if (remove) {
    file->RemoveProperty(propertyName);
  } else if (appendMode) {
    file->AppendProperty(&makefile, propertyName, propertyValue,
                         appendAsString);
  } else {
    file->SetProperty(&makefile, propertyName, propertyValue);
  }
  return true;
}
}
