/* 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>

#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()->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 {
      /* 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;
}
