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

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

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

  // Check and see if the value has been stored in the cache
  // already, if so use that value
  if (args.size() >= 4 && args.back() == "CACHE") {
    const char* cacheValue = status.GetMakefile().GetDefinition(args.front());
    if (cacheValue && !cmIsNOTFOUND(cacheValue)) {
      return true;
    }
  }

  std::string result;
  std::string filename = args[1];
  if (filename.find("[HKEY") != std::string::npos) {
    // Check the registry as the target application would view it.
    cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32;
    cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64;
    if (status.GetMakefile().PlatformIs64Bit()) {
      view = cmSystemTools::KeyWOW64_64;
      other_view = cmSystemTools::KeyWOW64_32;
    }
    cmSystemTools::ExpandRegistryValues(filename, view);
    if (filename.find("/registry") != std::string::npos) {
      std::string other = args[1];
      cmSystemTools::ExpandRegistryValues(other, other_view);
      if (other.find("/registry") == std::string::npos) {
        filename = other;
      }
    }
  }
  std::string storeArgs;
  std::string programArgs;
  if (args[2] == "DIRECTORY" || args[2] == "PATH") {
    result = cmSystemTools::GetFilenamePath(filename);
  } else if (args[2] == "NAME") {
    result = cmSystemTools::GetFilenameName(filename);
  } else if (args[2] == "PROGRAM") {
    for (unsigned int i = 2; i < args.size(); ++i) {
      if (args[i] == "PROGRAM_ARGS") {
        i++;
        if (i < args.size()) {
          storeArgs = args[i];
        }
      }
    }

    // First assume the path to the program was specified with no
    // arguments and with no quoting or escaping for spaces.
    // Only bother doing this if there is non-whitespace.
    if (!cmTrimWhitespace(filename).empty()) {
      result = cmSystemTools::FindProgram(filename);
    }

    // If that failed then assume a command-line string was given
    // and split the program part from the rest of the arguments.
    if (result.empty()) {
      std::string program;
      if (cmSystemTools::SplitProgramFromArgs(filename, program,
                                              programArgs)) {
        if (cmSystemTools::FileExists(program)) {
          result = program;
        } else {
          result = cmSystemTools::FindProgram(program);
        }
      }
      if (result.empty()) {
        programArgs.clear();
      }
    }
  } else if (args[2] == "EXT") {
    result = cmSystemTools::GetFilenameExtension(filename);
  } else if (args[2] == "NAME_WE") {
    result = cmSystemTools::GetFilenameWithoutExtension(filename);
  } else if (args[2] == "LAST_EXT") {
    result = cmSystemTools::GetFilenameLastExtension(filename);
  } else if (args[2] == "NAME_WLE") {
    result = cmSystemTools::GetFilenameWithoutLastExtension(filename);
  } else if (args[2] == "ABSOLUTE" || args[2] == "REALPATH") {
    // If the path given is relative, evaluate it relative to the
    // current source directory unless the user passes a different
    // base directory.
    std::string baseDir = status.GetMakefile().GetCurrentSourceDirectory();
    for (unsigned int i = 3; i < args.size(); ++i) {
      if (args[i] == "BASE_DIR") {
        ++i;
        if (i < args.size()) {
          baseDir = args[i];
        }
      }
    }
    // Collapse the path to its simplest form.
    result = cmSystemTools::CollapseFullPath(filename, baseDir);
    if (args[2] == "REALPATH") {
      // Resolve symlinks if possible
      result = cmSystemTools::GetRealPath(result);
    }
  } else {
    std::string err = "unknown component " + args[2];
    status.SetError(err);
    cmSystemTools::SetFatalErrorOccured();
    return false;
  }

  if (args.size() >= 4 && args.back() == "CACHE") {
    if (!programArgs.empty() && !storeArgs.empty()) {
      status.GetMakefile().AddCacheDefinition(
        storeArgs, programArgs, "",
        args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
    }
    status.GetMakefile().AddCacheDefinition(
      args.front(), result, "",
      args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
  } else {
    if (!programArgs.empty() && !storeArgs.empty()) {
      status.GetMakefile().AddDefinition(storeArgs, programArgs);
    }
    status.GetMakefile().AddDefinition(args.front(), result);
  }

  return true;
}
