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

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

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

#include "cmsys/String.h"

#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(
  cm::string_view path, OutputFormat format, bool useWatcomQuote) const
{
#ifdef _WIN32
  // Cache the short paths since `GetShortPathNameW` is really expensive.
  static std::unordered_map<std::string, std::string> shortPathCache{};

  // If this is a windows shell, the path has a space, and the path already
  // exists, we can use a short-path to reference it without a space.
  if (this->GetState()->UseWindowsShell() &&
      path.find_first_of(" #") != std::string::npos) {
    auto origPath = std::string(path);
    if (cmSystemTools::FileExists(origPath)) {
      auto i = shortPathCache.find(origPath);
      if (i == shortPathCache.end()) {
        std::string shortPath;
        if (!cmSystemTools::GetShortPath(origPath, shortPath)) {
          // Fallback for cases when Windows refuses to resolve
          // the short path, like for `C:\Program Files\WindowsApps\...`.
          shortPath = origPath;
        }
        i = shortPathCache.emplace(std::move(origPath), std::move(shortPath))
              .first;
      }
      path = i->second;
    }
  }
#endif

  // Otherwise, perform standard conversion.
  return this->ConvertToOutputFormat(path, 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;
  }
  if (this->GetState()->UseFastbuildMake()) {
    // Fastbuild needs to escape very few characters.
    flags = Shell_Flag_Fastbuild;
  }

  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 (char const 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 == '_' || cmsysString_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;
  }

  if (flags & Shell_Flag_Fastbuild) {
    return false;
  }

  /* 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) ||
        (c == ';' && (flags & Shell_Flag_VSIDE))) {
      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 if (flags & Shell_Flag_Fastbuild) {
        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 VS a semicolon is written `";"` inside a quoted argument.
           It ends quoting, inserts the `;`, and restarts quoting.  */
        out += "\";\"";
      } else {
        /* Otherwise a semicolon is written just ;. */
        out += ';';
      }
    } else if (*cit == '\n') {
      if (flags & Shell_Flag_Ninja) {
        out += "$\n";
      } else {
        out += '\n';
      }
    } else if (*cit == '^' && (flags & Shell_Flag_Fastbuild)) {
      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;
}
