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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <set>
#include <vector>

#ifdef _WIN32
#  include <unordered_map>
#  include <utility>
#endif

#include "cmList.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmSystemTools.h"
#include "cmValue.h"

namespace {
bool PathEqOrSubDir(std::string const& a, std::string const& b)
{
  return (cmSystemTools::ComparePath(a, b) ||
          cmSystemTools::IsSubDirectory(a, b));
}
}

cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot)
  : StateSnapshot(snapshot)
{
  assert(this->StateSnapshot.IsValid());
  this->ComputeRelativePathTopSource();
  this->ComputeRelativePathTopBinary();
  this->ComputeRelativePathTopRelation();
}

void cmOutputConverter::ComputeRelativePathTopSource()
{
  // Walk up the buildsystem directory tree to find the highest source
  // directory that contains the current source directory.
  cmStateSnapshot snapshot = this->StateSnapshot;
  for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent();
       parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) {
    if (cmSystemTools::IsSubDirectory(
          snapshot.GetDirectory().GetCurrentSource(),
          parent.GetDirectory().GetCurrentSource())) {
      snapshot = parent;
    }
  }
  this->RelativePathTopSource = snapshot.GetDirectory().GetCurrentSource();
}

void cmOutputConverter::ComputeRelativePathTopBinary()
{
  // Walk up the buildsystem directory tree to find the highest binary
  // directory that contains the current binary directory.
  cmStateSnapshot snapshot = this->StateSnapshot;
  for (cmStateSnapshot parent = snapshot.GetBuildsystemDirectoryParent();
       parent.IsValid(); parent = parent.GetBuildsystemDirectoryParent()) {
    if (cmSystemTools::IsSubDirectory(
          snapshot.GetDirectory().GetCurrentBinary(),
          parent.GetDirectory().GetCurrentBinary())) {
      snapshot = parent;
    }
  }

  this->RelativePathTopBinary = snapshot.GetDirectory().GetCurrentBinary();
}

void cmOutputConverter::ComputeRelativePathTopRelation()
{
  if (cmSystemTools::ComparePath(this->RelativePathTopSource,
                                 this->RelativePathTopBinary)) {
    this->RelativePathTopRelation = TopRelation::InSource;
  } else if (cmSystemTools::IsSubDirectory(this->RelativePathTopBinary,
                                           this->RelativePathTopSource)) {
    this->RelativePathTopRelation = TopRelation::BinInSrc;
  } else if (cmSystemTools::IsSubDirectory(this->RelativePathTopSource,
                                           this->RelativePathTopBinary)) {
    this->RelativePathTopRelation = TopRelation::SrcInBin;
  } else {
    this->RelativePathTopRelation = TopRelation::Separate;
  }
}

std::string const& cmOutputConverter::GetRelativePathTopSource() const
{
  return this->RelativePathTopSource;
}

std::string const& cmOutputConverter::GetRelativePathTopBinary() const
{
  return this->RelativePathTopBinary;
}

void cmOutputConverter::SetRelativePathTop(std::string const& topSource,
                                           std::string const& topBinary)
{
  this->RelativePathTopSource = topSource;
  this->RelativePathTopBinary = topBinary;
  this->ComputeRelativePathTopRelation();
}

std::string cmOutputConverter::MaybeRelativeTo(
  std::string const& local_path, std::string const& remote_path) const
{
  bool localInBinary = PathEqOrSubDir(local_path, this->RelativePathTopBinary);
  bool remoteInBinary =
    PathEqOrSubDir(remote_path, this->RelativePathTopBinary);

  bool localInSource = PathEqOrSubDir(local_path, this->RelativePathTopSource);
  bool remoteInSource =
    PathEqOrSubDir(remote_path, this->RelativePathTopSource);

  switch (this->RelativePathTopRelation) {
    case TopRelation::Separate:
      // Checks are independent.
      break;
    case TopRelation::BinInSrc:
      localInSource = localInSource && !localInBinary;
      remoteInSource = remoteInSource && !remoteInBinary;
      break;
    case TopRelation::SrcInBin:
      localInBinary = localInBinary && !localInSource;
      remoteInBinary = remoteInBinary && !remoteInSource;
      break;
    case TopRelation::InSource:
      // Checks are identical.
      break;
  };

  bool const bothInBinary = localInBinary && remoteInBinary;
  bool const bothInSource = localInSource && remoteInSource;

  if (bothInBinary || bothInSource) {
    return cmSystemTools::ForceToRelativePath(local_path, remote_path);
  }
  return remote_path;
}

std::string cmOutputConverter::MaybeRelativeToTopBinDir(
  std::string const& path) const
{
  return this->MaybeRelativeTo(this->GetState()->GetBinaryDirectory(), path);
}

std::string cmOutputConverter::MaybeRelativeToCurBinDir(
  std::string const& path) const
{
  return this->MaybeRelativeTo(
    this->StateSnapshot.GetDirectory().GetCurrentBinary(), path);
}

std::string cmOutputConverter::ConvertToOutputForExisting(
  const std::string& remote, OutputFormat format, bool useWatcomQuote) const
{
#ifdef _WIN32
  // Cache the Short Paths since we only convert the same few paths anyway and
  // calling `GetShortPathNameW` is really expensive.
  static std::unordered_map<std::string, std::string> shortPathCache{};

  // If this is a windows shell, the result has a space, and the path
  // already exists, we can use a short-path to reference it without a
  // space.
  if (this->GetState()->UseWindowsShell() &&
      remote.find_first_of(" #") != std::string::npos &&
      cmSystemTools::FileExists(remote)) {

    std::string shortPath = [&]() {
      auto cachedShortPathIt = shortPathCache.find(remote);

      if (cachedShortPathIt != shortPathCache.end()) {
        return cachedShortPathIt->second;
      }

      std::string tmp{};
      cmsys::Status status = cmSystemTools::GetShortPath(remote, tmp);
      if (!status) {
        // Fallback for cases when Windows refuses to resolve the short path,
        // like for C:\Program Files\WindowsApps\...
        tmp = remote;
      }
      shortPathCache[remote] = tmp;
      return tmp;
    }();

    return this->ConvertToOutputFormat(shortPath, format, useWatcomQuote);
  }
#endif

  // Otherwise, perform standard conversion.
  return this->ConvertToOutputFormat(remote, format, useWatcomQuote);
}

std::string cmOutputConverter::ConvertToOutputFormat(cm::string_view source,
                                                     OutputFormat format,
                                                     bool useWatcomQuote) const
{
  std::string result(source);
  // Convert it to an output path.
  if (format == SHELL || format == NINJAMULTI) {
    result = this->ConvertDirectorySeparatorsForShell(source);
    result = this->EscapeForShell(result, true, false, useWatcomQuote,
                                  format == NINJAMULTI);
  } else if (format == RESPONSE) {
    result =
      this->EscapeForShell(result, false, false, useWatcomQuote, false, true);
  }
  return result;
}

std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
  cm::string_view source) const
{
  std::string result(source);
  // For the MSYS shell convert drive letters to posix paths, so
  // that c:/some/path becomes /c/some/path.  This is needed to
  // avoid problems with the shell path translation.
  if (this->GetState()->UseMSYSShell() && !this->LinkScriptShell) {
    if (result.size() > 2 && result[1] == ':') {
      result[1] = result[0];
      result[0] = '/';
    }
  }
  if (this->GetState()->UseWindowsShell()) {
    std::replace(result.begin(), result.end(), '/', '\\');
  }
  return result;
}

static bool cmOutputConverterIsShellOperator(cm::string_view str)
{
  static std::set<cm::string_view> const shellOperators{
    "<", ">", "<<", ">>", "|", "||", "&&", "&>", "1>", "2>", "2>&1", "1>&2"
  };
  return (shellOperators.count(str) != 0);
}

std::string cmOutputConverter::EscapeForShell(cm::string_view str,
                                              bool makeVars, bool forEcho,
                                              bool useWatcomQuote,
                                              bool unescapeNinjaConfiguration,
                                              bool forResponse) const
{
  // Compute the flags for the target shell environment.
  int flags = 0;
  if (this->GetState()->UseWindowsVSIDE()) {
    flags |= Shell_Flag_VSIDE;
  } else if (!this->LinkScriptShell) {
    flags |= Shell_Flag_Make;
  }
  if (unescapeNinjaConfiguration) {
    flags |= Shell_Flag_UnescapeNinjaConfiguration;
  }
  if (makeVars) {
    flags |= Shell_Flag_AllowMakeVariables;
  }
  if (forEcho) {
    flags |= Shell_Flag_EchoWindows;
  }
  if (useWatcomQuote) {
    flags |= Shell_Flag_WatcomQuote;
  }
  if (forResponse) {
    flags |= Shell_Flag_IsResponse;
  }
  if (this->GetState()->UseWatcomWMake()) {
    flags |= Shell_Flag_WatcomWMake;
  }
  if (this->GetState()->UseMinGWMake()) {
    flags |= Shell_Flag_MinGWMake;
  }
  if (this->GetState()->UseNMake()) {
    flags |= Shell_Flag_NMake;
  }
  if (this->GetState()->UseNinja()) {
    flags |= Shell_Flag_Ninja;
  }
  if (!this->GetState()->UseWindowsShell()) {
    flags |= Shell_Flag_IsUnix;
  }

  return cmOutputConverter::EscapeForShell(str, flags);
}

std::string cmOutputConverter::EscapeForShell(cm::string_view str, int flags)
{
  // Do not escape shell operators.
  if (cmOutputConverterIsShellOperator(str)) {
    return std::string(str);
  }

  return Shell_GetArgument(str, flags);
}

std::string cmOutputConverter::EscapeForCMake(cm::string_view str,
                                              WrapQuotes wrapQuotes)
{
  // Always double-quote the argument to take care of most escapes.
  std::string result = (wrapQuotes == WrapQuotes::Wrap) ? "\"" : "";
  for (const char c : str) {
    if (c == '"') {
      // Escape the double quote to avoid ending the argument.
      result += "\\\"";
    } else if (c == '$') {
      // Escape the dollar to avoid expanding variables.
      result += "\\$";
    } else if (c == '\\') {
      // Escape the backslash to avoid other escapes.
      result += "\\\\";
    } else {
      // Other characters will be parsed correctly.
      result += c;
    }
  }
  if (wrapQuotes == WrapQuotes::Wrap) {
    result += "\"";
  }
  return result;
}

std::string cmOutputConverter::EscapeWindowsShellArgument(cm::string_view arg,
                                                          int shell_flags)
{
  return Shell_GetArgument(arg, shell_flags);
}

cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
  cm::string_view value)
{
  FortranFormat format = FortranFormatNone;
  if (!value.empty()) {
    for (std::string const& fi : cmList(value)) {
      if (fi == "FIXED") {
        format = FortranFormatFixed;
      }
      if (fi == "FREE") {
        format = FortranFormatFree;
      }
    }
  }
  return format;
}

cmOutputConverter::FortranPreprocess cmOutputConverter::GetFortranPreprocess(
  cm::string_view value)
{
  if (value.empty()) {
    return FortranPreprocess::Unset;
  }

  return cmIsOn(value) ? FortranPreprocess::Needed
                       : FortranPreprocess::NotNeeded;
}

void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
{
  this->LinkScriptShell = linkScriptShell;
}

cmState* cmOutputConverter::GetState() const
{
  return this->StateSnapshot.GetState();
}

/*

Notes:

Make variable replacements open a can of worms.  Sometimes they should
be quoted and sometimes not.  Sometimes their replacement values are
already quoted.

VS variables cause problems.  In order to pass the referenced value
with spaces the reference must be quoted.  If the variable value ends
in a backslash then it will escape the ending quote!  In order to make
the ending backslash appear we need this:

  "$(InputDir)\"

However if there is not a trailing backslash then this will put a
quote in the value so we need:

  "$(InputDir)"

Make variable references are platform specific so we should probably
just NOT quote them and let the listfile author deal with it.

*/

/*
TODO: For windows echo:

To display a pipe (|) or redirection character (< or >) when using the
echo command, use a caret character immediately before the pipe or
redirection character (for example, ^>, ^<, or ^| ). If you need to
use the caret character itself (^), use two in a row (^^).
*/

/* Some helpers to identify character classes */
static bool Shell_CharIsWhitespace(char c)
{
  return ((c == ' ') || (c == '\t'));
}

static bool Shell_CharNeedsQuotesOnUnix(char c)
{
  return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
          (c == '&') || (c == '$') || (c == '(') || (c == ')') || (c == '~') ||
          (c == '<') || (c == '>') || (c == '|') || (c == '*') || (c == '^') ||
          (c == '\\'));
}

static bool Shell_CharNeedsQuotesOnWindows(char c)
{
  return ((c == '\'') || (c == '#') || (c == '&') || (c == '<') ||
          (c == '>') || (c == '|') || (c == '^'));
}

static bool Shell_CharIsMakeVariableName(char c)
{
  return c && (c == '_' || isalpha((static_cast<int>(c))));
}

bool cmOutputConverter::Shell_CharNeedsQuotes(char c, int flags)
{
  /* On Windows the built-in command shell echo never needs quotes.  */
  if (!(flags & Shell_Flag_IsUnix) && (flags & Shell_Flag_EchoWindows)) {
    return false;
  }

  /* On all platforms quotes are needed to preserve whitespace.  */
  if (Shell_CharIsWhitespace(c)) {
    return true;
  }

  /* Quote hyphens in response files */
  if (flags & Shell_Flag_IsResponse) {
    if (c == '-') {
      return true;
    }
  }

  if (flags & Shell_Flag_IsUnix) {
    /* On UNIX several special characters need quotes to preserve them.  */
    if (Shell_CharNeedsQuotesOnUnix(c)) {
      return true;
    }
  } else {
    /* On Windows several special characters need quotes to preserve them.  */
    if (Shell_CharNeedsQuotesOnWindows(c)) {
      return true;
    }
  }
  return false;
}

cm::string_view::iterator cmOutputConverter::Shell_SkipMakeVariables(
  cm::string_view::iterator c, cm::string_view::iterator end)
{
  while ((c != end && (c + 1) != end) && (*c == '$' && *(c + 1) == '(')) {
    cm::string_view::iterator skip = c + 2;
    while ((skip != end) && Shell_CharIsMakeVariableName(*skip)) {
      ++skip;
    }
    if ((skip != end) && *skip == ')') {
      c = skip + 1;
    } else {
      break;
    }
  }
  return c;
}

/*
Allowing make variable replacements opens a can of worms.  Sometimes
they should be quoted and sometimes not.  Sometimes their replacement
values are already quoted or contain escapes.

Some Visual Studio variables cause problems.  In order to pass the
referenced value with spaces the reference must be quoted.  If the
variable value ends in a backslash then it will escape the ending
quote!  In order to make the ending backslash appear we need this:

  "$(InputDir)\"

However if there is not a trailing backslash then this will put a
quote in the value so we need:

  "$(InputDir)"

This macro decides whether we quote an argument just because it
contains a make variable reference.  This should be replaced with a
flag later when we understand applications of this better.
*/
#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0

bool cmOutputConverter::Shell_ArgumentNeedsQuotes(cm::string_view in,
                                                  int flags)
{
  /* The empty string needs quotes.  */
  if (in.empty()) {
    return true;
  }

  /* Scan the string for characters that require quoting.  */
  for (cm::string_view::iterator cit = in.begin(), cend = in.end();
       cit != cend; ++cit) {
    /* Look for $(MAKEVAR) syntax if requested.  */
    if (flags & Shell_Flag_AllowMakeVariables) {
#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
      cm::string_view::iterator skip = Shell_SkipMakeVariables(cit, cend);
      if (skip != cit) {
        /* We need to quote make variable references to preserve the
           string with contents substituted in its place.  */
        return true;
      }
#else
      /* Skip over the make variable references if any are present.  */
      cit = Shell_SkipMakeVariables(cit, cend);

      /* Stop if we have reached the end of the string.  */
      if (cit == cend) {
        break;
      }
#endif
    }

    /* Check whether this character needs quotes.  */
    if (Shell_CharNeedsQuotes(*cit, flags)) {
      return true;
    }
  }

  /* On Windows some single character arguments need quotes.  */
  if (flags & Shell_Flag_IsUnix && in.size() == 1) {
    char c = in[0];
    if ((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) {
      return true;
    }
  }

  /* UNC paths in MinGW Makefiles need quotes.  */
  if ((flags & Shell_Flag_MinGWMake) && (flags & Shell_Flag_Make)) {
    if (in.size() > 1 && in[0] == '\\' && in[1] == '\\') {
      return true;
    }
  }

  return false;
}

std::string cmOutputConverter::Shell_GetArgument(cm::string_view in, int flags)
{
  /* Output will be at least as long as input string.  */
  std::string out;
  out.reserve(in.size());

  /* Keep track of how many backslashes have been encountered in a row.  */
  int windows_backslashes = 0;

  /* Whether the argument must be quoted.  */
  int needQuotes = Shell_ArgumentNeedsQuotes(in, flags);
  if (needQuotes) {
    /* Add the opening quote for this argument.  */
    if (flags & Shell_Flag_WatcomQuote) {
      if (flags & Shell_Flag_IsUnix) {
        out += '"';
      }
      out += '\'';
    } else {
      out += '"';
    }
  }

  /* Scan the string for characters that require escaping or quoting.  */
  for (cm::string_view::iterator cit = in.begin(), cend = in.end();
       cit != cend; ++cit) {
    /* Look for $(MAKEVAR) syntax if requested.  */
    if (flags & Shell_Flag_AllowMakeVariables) {
      cm::string_view::iterator skip = Shell_SkipMakeVariables(cit, cend);
      if (skip != cit) {
        /* Copy to the end of the make variable references.  */
        while (cit != skip) {
          out += *cit++;
        }

        /* The make variable reference eliminates any escaping needed
           for preceding backslashes.  */
        windows_backslashes = 0;

        /* Stop if we have reached the end of the string.  */
        if (cit == cend) {
          break;
        }
      }
    }

    /* Check whether this character needs escaping for the shell.  */
    if (flags & Shell_Flag_IsUnix) {
      /* On Unix a few special characters need escaping even inside a
         quoted argument.  */
      if (*cit == '\\' || *cit == '"' || *cit == '`' || *cit == '$') {
        /* This character needs a backslash to escape it.  */
        out += '\\';
      }
    } else if (flags & Shell_Flag_EchoWindows) {
      /* On Windows the built-in command shell echo never needs escaping.  */
    } else {
      /* On Windows only backslashes and double-quotes need escaping.  */
      if (*cit == '\\') {
        /* Found a backslash.  It may need to be escaped later.  */
        ++windows_backslashes;
      } else if (*cit == '"') {
        /* Found a double-quote.  Escape all immediately preceding
           backslashes.  */
        while (windows_backslashes > 0) {
          --windows_backslashes;
          out += '\\';
        }

        /* Add the backslash to escape the double-quote.  */
        out += '\\';
      } else {
        /* We encountered a normal character.  This eliminates any
           escaping needed for preceding backslashes.  */
        windows_backslashes = 0;
      }
    }

    /* Check whether this character needs escaping for a make tool.  */
    if (*cit == '$') {
      if (flags & Shell_Flag_Make) {
        /* In Makefiles a dollar is written $$.  The make tool will
           replace it with just $ before passing it to the shell.  */
        out += "$$";
      } else if (flags & Shell_Flag_VSIDE) {
        /* In a VS IDE a dollar is written "$".  If this is written in
           an un-quoted argument it starts a quoted segment, inserts
           the $ and ends the segment.  If it is written in a quoted
           argument it ends quoting, inserts the $ and restarts
           quoting.  Either way the $ is isolated from surrounding
           text to avoid looking like a variable reference.  */
        out += "\"$\"";
      } else {
        /* Otherwise a dollar is written just $. */
        out += '$';
      }
    } else if (*cit == '#') {
      if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
        /* In Watcom WMake makefiles a pound is written $#.  The make
           tool will replace it with just # before passing it to the
           shell.  */
        out += "$#";
      } else {
        /* Otherwise a pound is written just #. */
        out += '#';
      }
    } else if (*cit == '%') {
      if ((flags & Shell_Flag_VSIDE) ||
          ((flags & Shell_Flag_Make) &&
           ((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
        /* In the VS IDE, NMake, or MinGW make a percent is written %%.  */
        out += "%%";
      } else {
        /* Otherwise a percent is written just %. */
        out += '%';
      }
    } else if (*cit == ';') {
      if (flags & Shell_Flag_VSIDE) {
        /* In a VS IDE a semicolon is written ";".  If this is written
           in an un-quoted argument it starts a quoted segment,
           inserts the ; and ends the segment.  If it is written in a
           quoted argument it ends quoting, inserts the ; and restarts
           quoting.  Either way the ; is isolated.  */
        out += "\";\"";
      } else {
        /* Otherwise a semicolon is written just ;. */
        out += ';';
      }
    } else if (*cit == '\n') {
      if (flags & Shell_Flag_Ninja) {
        out += "$\n";
      } else {
        out += '\n';
      }
    } else {
      /* Store this character.  */
      out += *cit;
    }
  }

  if (needQuotes) {
    /* Add enough backslashes to escape any trailing ones.  */
    while (windows_backslashes > 0) {
      --windows_backslashes;
      out += '\\';
    }

    /* Add the closing quote for this argument.  */
    if (flags & Shell_Flag_WatcomQuote) {
      out += '\'';
      if (flags & Shell_Flag_IsUnix) {
        out += '"';
      }
    } else {
      out += '"';
    }
  }

  if (flags & Shell_Flag_UnescapeNinjaConfiguration) {
    std::string ninjaConfigReplace;
    if (flags & Shell_Flag_IsUnix) {
      ninjaConfigReplace += '\\';
    }
    ninjaConfigReplace += "$${CONFIGURATION}";
    cmSystemTools::ReplaceString(out, ninjaConfigReplace, "${CONFIGURATION}");
  }

  return out;
}
