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

#include "cmStringReplaceHelper.h"

#include "cmMakefile.h"
#include <sstream>
#include <utility>

cmStringReplaceHelper::cmStringReplaceHelper(const std::string& regex,
                                             std::string replace_expr,
                                             cmMakefile* makefile)
  : RegExString(regex)
  , RegularExpression(regex)
  , ReplaceExpression(std::move(replace_expr))
  , Makefile(makefile)
{
  this->ParseReplaceExpression();
}

bool cmStringReplaceHelper::Replace(const std::string& input,
                                    std::string& output)
{
  output.clear();

  // Scan through the input for all matches.
  std::string::size_type base = 0;
  while (this->RegularExpression.find(input.c_str() + base)) {
    if (this->Makefile != nullptr) {
      this->Makefile->ClearMatches();
      this->Makefile->StoreMatches(this->RegularExpression);
    }
    auto l2 = this->RegularExpression.start();
    auto r = this->RegularExpression.end();

    // Concatenate the part of the input that was not matched.
    output += input.substr(base, l2);

    // Make sure the match had some text.
    if (r - l2 == 0) {
      std::ostringstream error;
      error << "regex \"" << this->RegExString << "\" matched an empty string";
      this->ErrorString = error.str();
      return false;
    }

    // Concatenate the replacement for the match.
    for (const auto& replacement : this->Replacements) {
      if (replacement.Number < 0) {
        // This is just a plain-text part of the replacement.
        output += replacement.Value;
      } else {
        // Replace with part of the match.
        auto n = replacement.Number;
        auto start = this->RegularExpression.start(n);
        auto end = this->RegularExpression.end(n);
        auto len = input.length() - base;
        if ((start != std::string::npos) && (end != std::string::npos) &&
            (start <= len) && (end <= len)) {
          output += input.substr(base + start, end - start);
        } else {
          std::ostringstream error;
          error << "replace expression \"" << this->ReplaceExpression
                << "\" contains an out-of-range escape for regex \""
                << this->RegExString << "\"";
          this->ErrorString = error.str();
          return false;
        }
      }
    }

    // Move past the match.
    base += r;
  }

  // Concatenate the text after the last match.
  output += input.substr(base, input.length() - base);

  return true;
}

void cmStringReplaceHelper::ParseReplaceExpression()
{
  std::string::size_type l = 0;
  while (l < this->ReplaceExpression.length()) {
    auto r = this->ReplaceExpression.find('\\', l);
    if (r == std::string::npos) {
      r = this->ReplaceExpression.length();
      this->Replacements.emplace_back(
        this->ReplaceExpression.substr(l, r - l));
    } else {
      if (r - l > 0) {
        this->Replacements.emplace_back(
          this->ReplaceExpression.substr(l, r - l));
      }
      if (r == (this->ReplaceExpression.length() - 1)) {
        this->ValidReplaceExpression = false;
        this->ErrorString = "replace-expression ends in a backslash";
        return;
      }
      if ((this->ReplaceExpression[r + 1] >= '0') &&
          (this->ReplaceExpression[r + 1] <= '9')) {
        this->Replacements.emplace_back(this->ReplaceExpression[r + 1] - '0');
      } else if (this->ReplaceExpression[r + 1] == 'n') {
        this->Replacements.emplace_back("\n");
      } else if (this->ReplaceExpression[r + 1] == '\\') {
        this->Replacements.emplace_back("\\");
      } else {
        this->ValidReplaceExpression = false;
        std::ostringstream error;
        error << "Unknown escape \"" << this->ReplaceExpression.substr(r, 2)
              << "\" in replace-expression";
        this->ErrorString = error.str();
        return;
      }
      r += 2;
    }
    l = r;
  }
}
