/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
#ifndef @KWSYS_NAMESPACE@_SystemTools_hxx
#define @KWSYS_NAMESPACE@_SystemTools_hxx

#include <@KWSYS_NAMESPACE@/Configure.hxx>

#include <iosfwd>
#include <map>
#include <string>
#include <vector>

#include <sys/types.h>
// include sys/stat.h after sys/types.h
#include <sys/stat.h>

#if !defined(_WIN32) || defined(__CYGWIN__)
#  include <unistd.h> // For access permissions for use with access()
#endif

// Required for va_list
#include <stdarg.h>
// Required for FILE*
#include <stdio.h>
#if !defined(va_list)
// Some compilers move va_list into the std namespace and there is no way to
// tell that this has been done. Playing with things being included before or
// after stdarg.h does not solve things because we do not have control over
// what the user does. This hack solves this problem by moving va_list to our
// own namespace that is local for kwsys.
namespace std {
} // Required for platforms that do not have std namespace
namespace @KWSYS_NAMESPACE@_VA_LIST {
using namespace std;
typedef va_list hack_va_list;
}
namespace @KWSYS_NAMESPACE@ {
typedef @KWSYS_NAMESPACE@_VA_LIST::hack_va_list va_list;
}
#endif // va_list

namespace @KWSYS_NAMESPACE@ {

class SystemToolsStatic;

/** \class SystemToolsManager
 * \brief Use to make sure SystemTools is initialized before it is used
 * and is the last static object destroyed
 */
class @KWSYS_NAMESPACE@_EXPORT SystemToolsManager
{
public:
  SystemToolsManager();
  ~SystemToolsManager();

  SystemToolsManager(const SystemToolsManager&) = delete;
  SystemToolsManager& operator=(const SystemToolsManager&) = delete;
};

// This instance will show up in any translation unit that uses
// SystemTools. It will make sure SystemTools is initialized
// before it is used and is the last static object destroyed.
static SystemToolsManager SystemToolsManagerInstance;

// Flags for use with TestFileAccess.  Use a typedef in case any operating
// system in the future needs a special type.  These are flags that may be
// combined using the | operator.
typedef int TestFilePermissions;
#if defined(_WIN32) && !defined(__CYGWIN__)
// On Windows (VC), no system header defines these constants...
static const TestFilePermissions TEST_FILE_OK = 0;
static const TestFilePermissions TEST_FILE_READ = 4;
static const TestFilePermissions TEST_FILE_WRITE = 2;
static const TestFilePermissions TEST_FILE_EXECUTE = 1;
#else
// Standard POSIX constants
static const TestFilePermissions TEST_FILE_OK = F_OK;
static const TestFilePermissions TEST_FILE_READ = R_OK;
static const TestFilePermissions TEST_FILE_WRITE = W_OK;
static const TestFilePermissions TEST_FILE_EXECUTE = X_OK;
#endif

/** \class SystemTools
 * \brief A collection of useful platform-independent system functions.
 */
class @KWSYS_NAMESPACE@_EXPORT SystemTools
{
public:
  /** -----------------------------------------------------------------
   *               String Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Replace symbols in str that are not valid in C identifiers as
   * defined by the 1999 standard, ie. anything except [A-Za-z0-9_].
   * They are replaced with `_' and if the first character is a digit
   * then an underscore is prepended.  Note that this can produce
   * identifiers that the standard reserves (_[A-Z].* and __.*).
   */
  static std::string MakeCidentifier(const std::string& s);

  static std::string MakeCindentifier(const std::string& s)
  {
    return MakeCidentifier(s);
  }

  /**
   * Replace replace all occurrences of the string in the source string.
   */
  static void ReplaceString(std::string& source, const char* replace,
                            const char* with);
  static void ReplaceString(std::string& source, const std::string& replace,
                            const std::string& with);

  /**
   * Return a capitalized string (i.e the first letter is uppercased,
   * all other are lowercased).
   */
  static std::string Capitalized(const std::string&);

  /**
   * Return a 'capitalized words' string (i.e the first letter of each word
   * is uppercased all other are left untouched though).
   */
  static std::string CapitalizedWords(const std::string&);

  /**
   * Return a 'uncapitalized words' string (i.e the first letter of each word
   * is lowercased all other are left untouched though).
   */
  static std::string UnCapitalizedWords(const std::string&);

  /**
   * Return a lower case string
   */
  static std::string LowerCase(const std::string&);

  /**
   * Return a lower case string
   */
  static std::string UpperCase(const std::string&);

  /**
   * Count char in string
   */
  static size_t CountChar(const char* str, char c);

  /**
   * Remove some characters from a string.
   * Return a pointer to the new resulting string (allocated with 'new')
   */
  static char* RemoveChars(const char* str, const char* toremove);

  /**
   * Remove remove all but 0->9, A->F characters from a string.
   * Return a pointer to the new resulting string (allocated with 'new')
   */
  static char* RemoveCharsButUpperHex(const char* str);

  /**
   * Replace some characters by another character in a string (in-place)
   * Return a pointer to string
   */
  static char* ReplaceChars(char* str, const char* toreplace,
                            char replacement);

  /**
   * Returns true if str1 starts (respectively ends) with str2
   */
  static bool StringStartsWith(const char* str1, const char* str2);
  static bool StringStartsWith(const std::string& str1, const char* str2);
  static bool StringEndsWith(const char* str1, const char* str2);
  static bool StringEndsWith(const std::string& str1, const char* str2);

  /**
   * Returns a pointer to the last occurrence of str2 in str1
   */
  static const char* FindLastString(const char* str1, const char* str2);

  /**
   * Make a duplicate of the string similar to the strdup C function
   * but use new to create the 'new' string, so one can use
   * 'delete' to remove it. Returns 0 if the input is empty.
   */
  static char* DuplicateString(const char* str);

  /**
   * Return the string cropped to a given length by removing chars in the
   * center of the string and replacing them with an ellipsis (...)
   */
  static std::string CropString(const std::string&, size_t max_len);

  /** split a path by separator into an array of strings, default is /.
      If isPath is true then the string is treated like a path and if
      s starts with a / then the first element of the returned array will
      be /, so /foo/bar will be [/, foo, bar]
  */
  static std::vector<std::string> SplitString(const std::string& s,
                                              char separator = '/',
                                              bool isPath = false);
  /**
   * Perform a case-independent string comparison
   */
  static int Strucmp(const char* s1, const char* s2);

  /**
   * Split a string on its newlines into multiple lines
   * Return false only if the last line stored had no newline
   */
  static bool Split(const std::string& s, std::vector<std::string>& l);
  static bool Split(const std::string& s, std::vector<std::string>& l,
                    char separator);

  /**
   * Return string with space added between capitalized words
   * (i.e. EatMyShorts becomes Eat My Shorts )
   * (note that IEatShorts becomes IEat Shorts)
   */
  static std::string AddSpaceBetweenCapitalizedWords(const std::string&);

  /**
   * Append two or more strings and produce new one.
   * Programmer must 'delete []' the resulting string, which was allocated
   * with 'new'.
   * Return 0 if inputs are empty or there was an error
   */
  static char* AppendStrings(const char* str1, const char* str2);
  static char* AppendStrings(const char* str1, const char* str2,
                             const char* str3);

  /**
   * Estimate the length of the string that will be produced
   * from printing the given format string and arguments.  The
   * returned length will always be at least as large as the string
   * that will result from printing.
   * WARNING: since va_arg is called to iterate of the argument list,
   * you will not be able to use this 'ap' anymore from the beginning.
   * It's up to you to call va_end though.
   */
  static int EstimateFormatLength(const char* format, va_list ap);

  /**
   * Escape specific characters in 'str'.
   */
  static std::string EscapeChars(const char* str, const char* chars_to_escape,
                                 char escape_char = '\\');

  /** -----------------------------------------------------------------
   *               Filename Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Replace Windows file system slashes with Unix-style slashes.
   */
  static void ConvertToUnixSlashes(std::string& path);

#ifdef _WIN32
  /** Calls Encoding::ToWindowsExtendedPath.  */
  static std::wstring ConvertToWindowsExtendedPath(const std::string&);
#endif

  /**
   * For windows this calls ConvertToWindowsOutputPath and for unix
   * it calls ConvertToUnixOutputPath
   */
  static std::string ConvertToOutputPath(const std::string&);

  /**
   * Convert the path to a string that can be used in a unix makefile.
   * double slashes are removed, and spaces are escaped.
   */
  static std::string ConvertToUnixOutputPath(const std::string&);

  /**
   * Convert the path to string that can be used in a windows project or
   * makefile.   Double slashes are removed if they are not at the start of
   * the string, the slashes are converted to windows style backslashes, and
   * if there are spaces in the string it is double quoted.
   */
  static std::string ConvertToWindowsOutputPath(const std::string&);

  /**
   * Return true if a path with the given name exists in the current directory.
   */
  static bool PathExists(const std::string& path);

  /**
   * Return true if a file exists in the current directory.
   * If isFile = true, then make sure the file is a file and
   * not a directory.  If isFile = false, then return true
   * if it is a file or a directory.  Note that the file will
   * also be checked for read access.  (Currently, this check
   * for read access is only done on POSIX systems.)
   */
  static bool FileExists(const char* filename, bool isFile);
  static bool FileExists(const std::string& filename, bool isFile);
  static bool FileExists(const char* filename);
  static bool FileExists(const std::string& filename);

  /**
   * Test if a file exists and can be accessed with the requested
   * permissions.  Symbolic links are followed.  Returns true if
   * the access test was successful.
   *
   * On POSIX systems (including Cygwin), this maps to the access
   * function.  On Windows systems, all existing files are
   * considered readable, and writable files are considered to
   * have the read-only file attribute cleared.
   */
  static bool TestFileAccess(const char* filename,
                             TestFilePermissions permissions);
  static bool TestFileAccess(const std::string& filename,
                             TestFilePermissions permissions);
/**
 * Cross platform wrapper for stat struct
 */
#if defined(_WIN32) && !defined(__CYGWIN__)
  typedef struct _stat64 Stat_t;
#else
  typedef struct stat Stat_t;
#endif

  /**
   * Cross platform wrapper for stat system call
   *
   * On Windows this may not work for paths longer than 250 characters
   * due to limitations of the underlying '_wstat64' call.
   */
  static int Stat(const char* path, Stat_t* buf);
  static int Stat(const std::string& path, Stat_t* buf);

/**
 * Converts Cygwin path to Win32 path. Uses dictionary container for
 * caching and calls to cygwin_conv_to_win32_path from Cygwin dll
 * for actual translation.  Returns true on success, else false.
 */
#ifdef __CYGWIN__
  static bool PathCygwinToWin32(const char* path, char* win32_path);
#endif

  /**
   * Return file length
   */
  static unsigned long FileLength(const std::string& filename);

  /**
     Change the modification time or create a file
  */
  static bool Touch(const std::string& filename, bool create);

  /**
   *  Compare file modification times.
   *  Return true for successful comparison and false for error.
   *  When true is returned, result has -1, 0, +1 for
   *  f1 older, same, or newer than f2.
   */
  static bool FileTimeCompare(const std::string& f1, const std::string& f2,
                              int* result);

  /**
   *  Get the file extension (including ".") needed for an executable
   *  on the current platform ("" for unix, ".exe" for Windows).
   */
  static const char* GetExecutableExtension();

  /**
   * Given a path on a Windows machine, return the actual case of
   * the path as it exists on disk.  Path components that do not
   * exist on disk are returned unchanged.  Relative paths are always
   * returned unchanged.  Drive letters are always made upper case.
   * This does nothing on non-Windows systems but return the path.
   */
  static std::string GetActualCaseForPath(const std::string& path);

  /**
   * Given the path to a program executable, get the directory part of
   * the path with the file stripped off.  If there is no directory
   * part, the empty string is returned.
   */
  static std::string GetProgramPath(const std::string&);
  static bool SplitProgramPath(const std::string& in_name, std::string& dir,
                               std::string& file, bool errorReport = true);

  /**
   *  Given argv[0] for a unix program find the full path to a running
   *  executable.  argv0 can be null for windows WinMain programs
   *  in this case GetModuleFileName will be used to find the path
   *  to the running executable.  If argv0 is not a full path,
   *  then this will try to find the full path.  If the path is not
   *  found false is returned, if found true is returned.  An error
   *  message of the attempted paths is stored in errorMsg.
   *  exeName is the name of the executable.
   *  buildDir is a possibly null path to the build directory.
   *  installPrefix is a possibly null pointer to the install directory.
   */
  static bool FindProgramPath(const char* argv0, std::string& pathOut,
                              std::string& errorMsg,
                              const char* exeName = nullptr,
                              const char* buildDir = nullptr,
                              const char* installPrefix = nullptr);

  /**
   * Given a path to a file or directory, convert it to a full path.
   * This collapses away relative paths relative to the cwd argument
   * (which defaults to the current working directory).  The full path
   * is returned.
   */
  static std::string CollapseFullPath(std::string const& in_path);
  static std::string CollapseFullPath(std::string const& in_path,
                                      const char* in_base);
  static std::string CollapseFullPath(std::string const& in_path,
                                      std::string const& in_base);

  /**
   * Get the real path for a given path, removing all symlinks.  In
   * the event of an error (non-existent path, permissions issue,
   * etc.) the original path is returned if errorMessage pointer is
   * nullptr.  Otherwise empty string is returned and errorMessage
   * contains error description.
   */
  static std::string GetRealPath(const std::string& path,
                                 std::string* errorMessage = nullptr);

  /**
   * Split a path name into its root component and the rest of the
   * path.  The root component is one of the following:
   *    "/"   = UNIX full path
   *    "c:/" = Windows full path (can be any drive letter)
   *    "c:"  = Windows drive-letter relative path (can be any drive letter)
   *    "//"  = Network path
   *    "~/"  = Home path for current user
   *    "~u/" = Home path for user 'u'
   *    ""    = Relative path
   *
   * A pointer to the rest of the path after the root component is
   * returned.  The root component is stored in the "root" string if
   * given.
   */
  static const char* SplitPathRootComponent(const std::string& p,
                                            std::string* root = nullptr);

  /**
   * Split a path name into its basic components.  The first component
   * always exists and is the root returned by SplitPathRootComponent.
   * The remaining components form the path.  If there is a trailing
   * slash then the last component is the empty string.  The
   * components can be recombined as "c[0]c[1]/c[2]/.../c[n]" to
   * produce the original path.  Home directory references are
   * automatically expanded if expand_home_dir is true and this
   * platform supports them.
   *
   * This does *not* normalize the input path.  All components are
   * preserved, including empty ones.  Typically callers should use
   * this only on paths that have already been normalized.
   */
  static void SplitPath(const std::string& p,
                        std::vector<std::string>& components,
                        bool expand_home_dir = true);

  /**
   * Join components of a path name into a single string.  See
   * SplitPath for the format of the components.
   *
   * This does *not* normalize the input path.  All components are
   * preserved, including empty ones.  Typically callers should use
   * this only on paths that have already been normalized.
   */
  static std::string JoinPath(const std::vector<std::string>& components);
  static std::string JoinPath(std::vector<std::string>::const_iterator first,
                              std::vector<std::string>::const_iterator last);

  /**
   * Compare a path or components of a path.
   */
  static bool ComparePath(const std::string& c1, const std::string& c2);

  /**
   * Return path of a full filename (no trailing slashes)
   */
  static std::string GetFilenamePath(const std::string&);

  /**
   * Return file name of a full filename (i.e. file name without path)
   */
  static std::string GetFilenameName(const std::string&);

  /**
   * Return longest file extension of a full filename (dot included)
   */
  static std::string GetFilenameExtension(const std::string&);

  /**
   * Return shortest file extension of a full filename (dot included)
   */
  static std::string GetFilenameLastExtension(const std::string& filename);

  /**
   * Return file name without extension of a full filename
   */
  static std::string GetFilenameWithoutExtension(const std::string&);

  /**
   * Return file name without its last (shortest) extension
   */
  static std::string GetFilenameWithoutLastExtension(const std::string&);

  /**
   * Return whether the path represents a full path (not relative)
   */
  static bool FileIsFullPath(const std::string&);
  static bool FileIsFullPath(const char*);

  /**
   * For windows return the short path for the given path,
   * Unix just a pass through
   */
  static bool GetShortPath(const std::string& path, std::string& result);

  /**
   * Read line from file. Make sure to read a full line and truncates it if
   * requested via sizeLimit. Returns true if any data were read before the
   * end-of-file was reached. If the has_newline argument is specified, it will
   * be true when the line read had a newline character.
   */
  static bool GetLineFromStream(std::istream& istr, std::string& line,
                                bool* has_newline = nullptr,
                                long sizeLimit = -1);

  /**
   * Get the parent directory of the directory or file
   */
  static std::string GetParentDirectory(const std::string& fileOrDir);

  /**
   * Check if the given file or directory is in subdirectory of dir
   */
  static bool IsSubDirectory(const std::string& fileOrDir,
                             const std::string& dir);

  /** -----------------------------------------------------------------
   *               File Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Open a file considering unicode. On Windows, if 'e' is present in
   * mode it is first discarded.
   */
  static FILE* Fopen(const std::string& file, const char* mode);

/**
 * Visual C++ does not define mode_t.
 */
#if defined(_MSC_VER)
  typedef unsigned short mode_t;
#endif

  /**
   * Make a new directory if it is not there.  This function
   * can make a full path even if none of the directories existed
   * prior to calling this function.
   */
  static bool MakeDirectory(const char* path, const mode_t* mode = nullptr);
  static bool MakeDirectory(const std::string& path,
                            const mode_t* mode = nullptr);

  /**
   * Copy the source file to the destination file only
   * if the two files differ.
   */
  static bool CopyFileIfDifferent(const std::string& source,
                                  const std::string& destination);

  /**
   * Compare the contents of two files.  Return true if different
   */
  static bool FilesDiffer(const std::string& source,
                          const std::string& destination);

  /**
   * Compare the contents of two files, ignoring line ending differences.
   * Return true if different
   */
  static bool TextFilesDiffer(const std::string& path1,
                              const std::string& path2);

  /**
   * Return true if the two files are the same file
   */
  static bool SameFile(const std::string& file1, const std::string& file2);

  /**
   * Copy a file.
   */
  static bool CopyFileAlways(const std::string& source,
                             const std::string& destination);

  /**
   * Copy a file.  If the "always" argument is true the file is always
   * copied.  If it is false, the file is copied only if it is new or
   * has changed.
   */
  static bool CopyAFile(const std::string& source,
                        const std::string& destination, bool always = true);

  /**
   * Copy content directory to another directory with all files and
   * subdirectories.  If the "always" argument is true all files are
   * always copied.  If it is false, only files that have changed or
   * are new are copied.
   */
  static bool CopyADirectory(const std::string& source,
                             const std::string& destination,
                             bool always = true);

  /**
   * Remove a file
   */
  static bool RemoveFile(const std::string& source);

  /**
   * Remove a directory
   */
  static bool RemoveADirectory(const std::string& source);

  /**
   * Get the maximum full file path length
   */
  static size_t GetMaximumFilePathLength();

  /**
   * Find a file in the system PATH, with optional extra paths
   */
  static std::string FindFile(
    const std::string& name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);

  /**
   * Find a directory in the system PATH, with optional extra paths
   */
  static std::string FindDirectory(
    const std::string& name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);

  /**
   * Find an executable in the system PATH, with optional extra paths
   */
  static std::string FindProgram(
    const char* name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);
  static std::string FindProgram(
    const std::string& name,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);
  static std::string FindProgram(
    const std::vector<std::string>& names,
    const std::vector<std::string>& path = std::vector<std::string>(),
    bool no_system_path = false);

  /**
   * Find a library in the system PATH, with optional extra paths
   */
  static std::string FindLibrary(const std::string& name,
                                 const std::vector<std::string>& path);

  /**
   * Return true if the file is a directory
   */
  static bool FileIsDirectory(const std::string& name);

  /**
   * Return true if the file is an executable
   */
  static bool FileIsExecutable(const std::string& name);

  /**
   * Return true if the file is a symlink
   */
  static bool FileIsSymlink(const std::string& name);

  /**
   * Return true if the file is a FIFO
   */
  static bool FileIsFIFO(const std::string& name);

  /**
   * Return true if the file has a given signature (first set of bytes)
   */
  static bool FileHasSignature(const char* filename, const char* signature,
                               long offset = 0);

  /**
   * Attempt to detect and return the type of a file.
   * Up to 'length' bytes are read from the file, if more than 'percent_bin' %
   * of the bytes are non-textual elements, the file is considered binary,
   * otherwise textual. Textual elements are bytes in the ASCII [0x20, 0x7E]
   * range, but also \\n, \\r, \\t.
   * The algorithm is simplistic, and should probably check for usual file
   * extensions, 'magic' signature, unicode, etc.
   */
  enum FileTypeEnum
  {
    FileTypeUnknown,
    FileTypeBinary,
    FileTypeText
  };
  static SystemTools::FileTypeEnum DetectFileType(const char* filename,
                                                  unsigned long length = 256,
                                                  double percent_bin = 0.05);

  /**
   * Create a symbolic link if the platform supports it.  Returns whether
   * creation succeeded.
   */
  static bool CreateSymlink(const std::string& origName,
                            const std::string& newName);

  /**
   * Read the contents of a symbolic link.  Returns whether reading
   * succeeded.
   */
  static bool ReadSymlink(const std::string& newName, std::string& origName);

  /**
   * Try to locate the file 'filename' in the directory 'dir'.
   * If 'filename' is a fully qualified filename, the basename of the file is
   * used to check for its existence in 'dir'.
   * If 'dir' is not a directory, GetFilenamePath() is called on 'dir' to
   * get its directory first (thus, you can pass a filename as 'dir', as
   * a convenience).
   * 'filename_found' is assigned the fully qualified name/path of the file
   * if it is found (not touched otherwise).
   * If 'try_filename_dirs' is true, try to find the file using the
   * components of its path, i.e. if we are looking for c:/foo/bar/bill.txt,
   * first look for bill.txt in 'dir', then in 'dir'/bar, then in 'dir'/foo/bar
   * etc.
   * Return true if the file was found, false otherwise.
   */
  static bool LocateFileInDir(const char* filename, const char* dir,
                              std::string& filename_found,
                              int try_filename_dirs = 0);

  /** compute the relative path from local to remote.  local must
      be a directory.  remote can be a file or a directory.
      Both remote and local must be full paths.  Basically, if
      you are in directory local and you want to access the file in remote
      what is the relative path to do that.  For example:
      /a/b/c/d to /a/b/c1/d1 -> ../../c1/d1
      from /usr/src to /usr/src/test/blah/foo.cpp -> test/blah/foo.cpp
  */
  static std::string RelativePath(const std::string& local,
                                  const std::string& remote);

  /**
   * Return file's modified time
   */
  static long int ModifiedTime(const std::string& filename);

  /**
   * Return file's creation time (Win32: works only for NTFS, not FAT)
   */
  static long int CreationTime(const std::string& filename);

  /**
   * Get and set permissions of the file.  If honor_umask is set, the umask
   * is queried and applied to the given permissions.  Returns false if
   * failure.
   *
   * WARNING:  A non-thread-safe method is currently used to get the umask
   * if a honor_umask parameter is set to true.
   */
  static bool GetPermissions(const char* file, mode_t& mode);
  static bool GetPermissions(const std::string& file, mode_t& mode);
  static bool SetPermissions(const char* file, mode_t mode,
                             bool honor_umask = false);
  static bool SetPermissions(const std::string& file, mode_t mode,
                             bool honor_umask = false);

  /** -----------------------------------------------------------------
   *               Time Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /** Get current time in seconds since Posix Epoch (Jan 1, 1970).  */
  static double GetTime();

  /**
   * Get current date/time
   */
  static std::string GetCurrentDateTime(const char* format);

  /** -----------------------------------------------------------------
   *               Registry Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Specify access to the 32-bit or 64-bit application view of
   * registry values.  The default is to match the currently running
   * binary type.
   */
  enum KeyWOW64
  {
    KeyWOW64_Default,
    KeyWOW64_32,
    KeyWOW64_64
  };

  /**
   * Get a list of subkeys.
   */
  static bool GetRegistrySubKeys(const std::string& key,
                                 std::vector<std::string>& subkeys,
                                 KeyWOW64 view = KeyWOW64_Default);

  /**
   * Read a registry value
   */
  static bool ReadRegistryValue(const std::string& key, std::string& value,
                                KeyWOW64 view = KeyWOW64_Default);

  /**
   * Write a registry value
   */
  static bool WriteRegistryValue(const std::string& key,
                                 const std::string& value,
                                 KeyWOW64 view = KeyWOW64_Default);

  /**
   * Delete a registry value
   */
  static bool DeleteRegistryValue(const std::string& key,
                                  KeyWOW64 view = KeyWOW64_Default);

  /** -----------------------------------------------------------------
   *               Environment Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   *  Add the paths from the environment variable PATH to the
   *  string vector passed in.  If env is set then the value
   *  of env will be used instead of PATH.
   */
  static void GetPath(std::vector<std::string>& path,
                      const char* env = nullptr);

  /**
   * Read an environment variable
   */
  static const char* GetEnv(const char* key);
  static const char* GetEnv(const std::string& key);
  static bool GetEnv(const char* key, std::string& result);
  static bool GetEnv(const std::string& key, std::string& result);
  static bool HasEnv(const char* key);
  static bool HasEnv(const std::string& key);

  /** Put a string into the environment
      of the form var=value */
  static bool PutEnv(const std::string& env);

  /** Remove a string from the environment.
      Input is of the form "var" or "var=value" (value is ignored). */
  static bool UnPutEnv(const std::string& env);

  /**
   * Get current working directory CWD
   */
  static std::string GetCurrentWorkingDirectory();

  /**
   * Change directory to the directory specified
   */
  static int ChangeDirectory(const std::string& dir);

  /**
   * Get the result of strerror(errno)
   */
  static std::string GetLastSystemError();

  /**
   * When building DEBUG with MSVC, this enables a hook that prevents
   * error dialogs from popping up if the program is being run from
   * DART.
   */
  static void EnableMSVCDebugHook();

  /**
   * Get the width of the terminal window. The code may or may not work, so
   * make sure you have some reasonable defaults prepared if the code returns
   * some bogus size.
   */
  static int GetTerminalWidth();

#if @KWSYS_NAMESPACE@_SYSTEMTOOLS_USE_TRANSLATION_MAP
  /**
   * Add an entry in the path translation table.
   */
  static void AddTranslationPath(const std::string& dir,
                                 const std::string& refdir);

  /**
   * If dir is different after CollapseFullPath is called,
   * Then insert it into the path translation table
   */
  static void AddKeepPath(const std::string& dir);

  /**
   * Update path by going through the Path Translation table;
   */
  static void CheckTranslationPath(std::string& path);
#endif

  /**
   * Delay the execution for a specified amount of time specified
   * in milliseconds
   */
  static void Delay(unsigned int msec);

  /**
   * Get the operating system name and version
   * This is implemented for Win32 only for the moment
   */
  static std::string GetOperatingSystemNameAndVersion();

  /** -----------------------------------------------------------------
   *               URL Manipulation Routines
   *  -----------------------------------------------------------------
   */

  /**
   * Parse a character string :
   *       protocol://dataglom
   * and fill protocol as appropriate.
   * decode the dataglom using DecodeURL if set to true.
   * Return false if the URL does not have the required form, true otherwise.
   */
  static bool ParseURLProtocol(const std::string& URL, std::string& protocol,
                               std::string& dataglom, bool decode = false);

  /**
   * Parse a string (a URL without protocol prefix) with the form:
   *  protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath]
   * and fill protocol, username, password, hostname, dataport, and datapath
   * when values are found.
   * decode all string except the protocol using DecodeUrl if set to true.
   * Return true if the string matches the format; false otherwise.
   */
  static bool ParseURL(const std::string& URL, std::string& protocol,
                       std::string& username, std::string& password,
                       std::string& hostname, std::string& dataport,
                       std::string& datapath, bool decode = false);

  /**
   * Decode the percent-encoded string from an URL or an URI
   * into their correct char values.
   * Does not perform any other sort of validation.
   * Return the decoded string
   */
  static std::string DecodeURL(const std::string& url);

private:
  /**
   * Allocate the stl map that serve as the Path Translation table.
   */
  static void ClassInitialize();

  /**
   * Deallocate the stl map that serve as the Path Translation table.
   */
  static void ClassFinalize();

  /**
   * This method prevents warning on SGI
   */
  SystemToolsManager* GetSystemToolsManager()
  {
    return &SystemToolsManagerInstance;
  }

  friend class SystemToolsStatic;
  friend class SystemToolsManager;
};

} // namespace @KWSYS_NAMESPACE@

#endif
