/* 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 <sstream>
#include <utility>

#include "cmMakefile.h"

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;
  }
}
