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

#include "cmExecutionStatus.h"
#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"

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

  // watch for ENV signatures
  auto const& variable = args[0]; // VAR is always first
  if (cmHasLiteralPrefix(variable, "ENV{") && variable.size() > 5) {
    // what is the variable name
    auto const& varName = variable.substr(4, variable.size() - 5);
    std::string putEnvArg = varName + "=";

    // what is the current value if any
    std::string currValue;
    bool const currValueSet = cmSystemTools::GetEnv(varName, currValue);

    // will it be set to something, then set it
    if (args.size() > 1 && !args[1].empty()) {
      // but only if it is different from current value
      if (!currValueSet || currValue != args[1]) {
        putEnvArg += args[1];
        cmSystemTools::PutEnv(putEnvArg);
      }
      // if there's extra arguments, warn user
      // that they are ignored by this command.
      if (args.size() > 2) {
        std::string m = "Only the first value argument is used when setting "
                        "an environment variable.  Argument '" +
          args[2] + "' and later are unused.";
        status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m);
      }
      return true;
    }

    // if it will be cleared, then clear it if it isn't already clear
    if (currValueSet) {
      cmSystemTools::PutEnv(putEnvArg);
    }
    return true;
  }

  // SET (VAR) // Removes the definition of VAR.
  if (args.size() == 1) {
    status.GetMakefile().RemoveDefinition(variable);
    return true;
  }
  // SET (VAR PARENT_SCOPE) // Removes the definition of VAR
  // in the parent scope.
  if (args.size() == 2 && args.back() == "PARENT_SCOPE") {
    status.GetMakefile().RaiseScope(variable, nullptr);
    return true;
  }

  // here are the remaining options
  //  SET (VAR value )
  //  SET (VAR value PARENT_SCOPE)
  //  SET (VAR CACHE TYPE "doc String" [FORCE])
  //  SET (VAR value CACHE TYPE "doc string" [FORCE])
  std::string value;  // optional
  bool cache = false; // optional
  bool force = false; // optional
  bool parentScope = false;
  cmStateEnums::CacheEntryType type =
    cmStateEnums::STRING; // required if cache
  cmValue docstring;      // required if cache

  unsigned int ignoreLastArgs = 0;
  // look for PARENT_SCOPE argument
  if (args.size() > 1 && args.back() == "PARENT_SCOPE") {
    parentScope = true;
    ignoreLastArgs++;
  } else {
    // look for FORCE argument
    if (args.size() > 4 && args.back() == "FORCE") {
      force = true;
      ignoreLastArgs++;
    }

    // check for cache signature
    if (args.size() > 3 &&
        args[args.size() - 3 - (force ? 1 : 0)] == "CACHE") {
      cache = true;
      ignoreLastArgs += 3;
    }
  }

  // collect any values into a single semi-colon separated value list
  value =
    cmList::to_string(cmMakeRange(args).advance(1).retreat(ignoreLastArgs));

  if (parentScope) {
    status.GetMakefile().RaiseScope(variable, value.c_str());
    return true;
  }

  // we should be nice and try to catch some simple screwups if the last or
  // next to last args are CACHE then they screwed up.  If they used FORCE
  // without CACHE they screwed up
  if (args.back() == "CACHE") {
    status.SetError(
      "given invalid arguments for CACHE mode: missing type and docstring");
    return false;
  }
  if (args.size() > 1 && args[args.size() - 2] == "CACHE") {
    status.SetError(
      "given invalid arguments for CACHE mode: missing type or docstring");
    return false;
  }
  if (force && !cache) {
    status.SetError("given invalid arguments: FORCE specified without CACHE");
    return false;
  }

  if (cache) {
    std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0);
    if (!cmState::StringToCacheEntryType(args[cacheStart + 1], type)) {
      std::string m = "implicitly converting '" + args[cacheStart + 1] +
        "' to 'STRING' type.";
      status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m);
      // Setting this may not be required, since it's
      // initialized as a string. Keeping this here to
      // ensure that the type is actually converting to a string.
      type = cmStateEnums::STRING;
    }
    docstring = cmValue{ args[cacheStart + 2] };
  }

  // see if this is already in the cache
  cmState* state = status.GetMakefile().GetState();
  cmValue existingValue = state->GetCacheEntryValue(variable);
  if (existingValue &&
      (state->GetCacheEntryType(variable) != cmStateEnums::UNINITIALIZED)) {
    // if the set is trying to CACHE the value but the value
    // is already in the cache and the type is not internal
    // then leave now without setting any definitions in the cache
    // or the makefile
    if (cache && type != cmStateEnums::INTERNAL && !force) {
      return true;
    }
  }

  // if it is meant to be in the cache then define it in the cache
  if (cache) {
    status.GetMakefile().AddCacheDefinition(variable, cmValue{ value },
                                            docstring, type, force);
  } else {
    // add the definition
    status.GetMakefile().AddDefinition(variable, value);
  }
  return true;
}
