// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/strings/str_replace.h"

#include <cstring>
#include <string>

#include "benchmark/benchmark.h"
#include "absl/base/internal/raw_logging.h"

namespace {

std::string* big_string;
std::string* after_replacing_the;
std::string* after_replacing_many;

struct Replacement {
  const char* needle;
  const char* replacement;
} replacements[] = {
    {"the", "box"},          //
    {"brown", "quick"},      //
    {"jumped", "liquored"},  //
    {"dozen", "brown"},      //
    {"lazy", "pack"},        //
    {"liquor", "shakes"},    //
};

// Here, we set up a std::string for use in global-replace benchmarks.
// We started with a million blanks, and then deterministically insert
// 10,000 copies each of two pangrams.  The result is a std::string that is
// 40% blank space and 60% these words.  'the' occurs 18,247 times and
// all the substitutions together occur 49,004 times.
//
// We then create "after_replacing_the" to be a std::string that is a result of
// replacing "the" with "box" in big_string.
//
// And then we create "after_replacing_many" to be a std::string that is result
// of preferring several substitutions.
void SetUpStrings() {
  if (big_string == nullptr) {
    size_t r = 0;
    big_string = new std::string(1000 * 1000, ' ');
    for (std::string phrase : {"the quick brown fox jumped over the lazy dogs",
                          "pack my box with the five dozen liquor jugs"}) {
      for (int i = 0; i < 10 * 1000; ++i) {
        r = r * 237 + 41;  // not very random.
        memcpy(&(*big_string)[r % (big_string->size() - phrase.size())],
               phrase.data(), phrase.size());
      }
    }
    // big_string->resize(50);
    // OK, we've set up the std::string, now let's set up expectations - first by
    // just replacing "the" with "box"
    after_replacing_the = new std::string(*big_string);
    for (size_t pos = 0;
         (pos = after_replacing_the->find("the", pos)) != std::string::npos;) {
      memcpy(&(*after_replacing_the)[pos], "box", 3);
    }
    // And then with all the replacements.
    after_replacing_many = new std::string(*big_string);
    for (size_t pos = 0;;) {
      size_t next_pos = static_cast<size_t>(-1);
      const char* needle_string = nullptr;
      const char* replacement_string = nullptr;
      for (const auto& r : replacements) {
        auto needlepos = after_replacing_many->find(r.needle, pos);
        if (needlepos != std::string::npos && needlepos < next_pos) {
          next_pos = needlepos;
          needle_string = r.needle;
          replacement_string = r.replacement;
        }
      }
      if (next_pos > after_replacing_many->size()) break;
      after_replacing_many->replace(next_pos, strlen(needle_string),
                                    replacement_string);
      next_pos += strlen(replacement_string);
      pos = next_pos;
    }
  }
}

void BM_StrReplaceAllOneReplacement(benchmark::State& state) {
  SetUpStrings();
  std::string src = *big_string;
  for (auto _ : state) {
    std::string dest = absl::StrReplaceAll(src, {{"the", "box"}});
    ABSL_RAW_CHECK(dest == *after_replacing_the,
                   "not benchmarking intended behavior");
  }
}
BENCHMARK(BM_StrReplaceAllOneReplacement);

void BM_StrReplaceAll(benchmark::State& state) {
  SetUpStrings();
  std::string src = *big_string;
  for (auto _ : state) {
    std::string dest = absl::StrReplaceAll(src, {{"the", "box"},
                                            {"brown", "quick"},
                                            {"jumped", "liquored"},
                                            {"dozen", "brown"},
                                            {"lazy", "pack"},
                                            {"liquor", "shakes"}});
    ABSL_RAW_CHECK(dest == *after_replacing_many,
                   "not benchmarking intended behavior");
  }
}
BENCHMARK(BM_StrReplaceAll);

}  // namespace
