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

#include <cstring>

#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

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

  auto arg = args.begin();

  // The first argument is the cache entry name.
  std::string const& cacheEntry = *arg++;
  cmProp cacheValue = status.GetMakefile().GetDefinition(cacheEntry);
  // If it exists already and appears up to date then we are done.  If
  // the string contains "(IntDir)" but that is not the
  // CMAKE_CFG_INTDIR setting then the value is out of date.
  std::string const& intDir =
    status.GetMakefile().GetRequiredDefinition("CMAKE_CFG_INTDIR");

  bool haveCacheValue = false;
  if (status.GetMakefile().IsOn("CMAKE_CROSSCOMPILING")) {
    haveCacheValue = (cacheValue != nullptr);
    if (!haveCacheValue) {
      std::string msg = cmStrCat(
        "UTILITY_SOURCE is used in cross compiling mode for ", cacheEntry,
        ". If your intention is to run this executable, you need to "
        "preload the cache with the full path to a version of that "
        "program, which runs on this build machine.");
      cmSystemTools::Message(msg, "Warning");
    }
  } else {
    cmState* state = status.GetMakefile().GetState();
    haveCacheValue = (cacheValue &&
                      (strstr(cacheValue->c_str(), "(IntDir)") == nullptr ||
                       (intDir == "$(IntDir)")) &&
                      (state->GetCacheMajorVersion() != 0 &&
                       state->GetCacheMinorVersion() != 0));
  }

  if (haveCacheValue) {
    return true;
  }

  // The second argument is the utility's executable name, which will be
  // needed later.
  std::string const& utilityName = *arg++;

  // The third argument specifies the relative directory of the source
  // of the utility.
  std::string const& relativeSource = *arg++;
  std::string utilitySource = status.GetMakefile().GetCurrentSourceDirectory();
  utilitySource = utilitySource + "/" + relativeSource;

  // If the directory doesn't exist, the source has not been included.
  if (!cmSystemTools::FileExists(utilitySource)) {
    return true;
  }

  // Make sure all the files exist in the source directory.
  while (arg != args.end()) {
    std::string file = utilitySource + "/" + *arg++;
    if (!cmSystemTools::FileExists(file)) {
      return true;
    }
  }

  // The source exists.
  const std::string& cmakeCFGout =
    status.GetMakefile().GetRequiredDefinition("CMAKE_CFG_INTDIR");
  std::string utilityDirectory =
    status.GetMakefile().GetCurrentBinaryDirectory();
  std::string exePath;
  if (cmProp d =
        status.GetMakefile().GetDefinition("EXECUTABLE_OUTPUT_PATH")) {
    exePath = *d;
  }
  if (!exePath.empty()) {
    utilityDirectory = exePath;
  } else {
    utilityDirectory += "/" + relativeSource;
  }

  // Construct the cache entry for the executable's location.
  std::string utilityExecutable = utilityDirectory + "/" + cmakeCFGout + "/" +
    utilityName +
    *status.GetMakefile().GetDefinition("CMAKE_EXECUTABLE_SUFFIX");

  // make sure we remove any /./ in the name
  cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");

  // Enter the value into the cache.
  status.GetMakefile().AddCacheDefinition(cacheEntry, utilityExecutable,
                                          "Path to an internal program.",
                                          cmStateEnums::FILEPATH);
  // add a value into the cache that maps from the
  // full path to the name of the project
  cmSystemTools::ConvertToUnixSlashes(utilityExecutable);
  status.GetMakefile().AddCacheDefinition(utilityExecutable, utilityName,
                                          "Executable to project name.",
                                          cmStateEnums::INTERNAL);

  return true;
}
