/* 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 "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.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++;
  cmValue 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 (cmValue 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;
}
