/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * 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 "src/trace_processor/util/glob.h"

#include <benchmark/benchmark.h>
#include <sqlite3.h>

#include "perfetto/ext/base/scoped_file.h"

namespace {

using namespace perfetto;
using benchmark::Counter;
using perfetto::trace_processor::util::GlobMatcher;

static const char kAndroidGlob[] = "*android*";
static const char kLaunchingGlob[] = "launching: *";
static const char kChoreographerGlob[] = "Choreographer#doFrame*";
static const char kQuestionMarkGlob[] = "Choreo?rapher#doFrame*";
static const char kCharClassGlob[] = "Choreo[a-z]rapher#doFrame*";

std::vector<std::string> LoadTraceStrings(benchmark::State& state) {
  std::vector<std::string> strs;
  // This requires that the user has downloaded the file
  // go/perfetto-benchmark-slice-strings into /tmp/trace_strings. The file is
  // too big (220 MB after uncompression) and it's not worth adding it to the
  // //test/data. Also it contains data from a team member's phone and cannot
  // be public.
  base::ScopedFstream f(fopen("/tmp/slice_strings", "re"));
  if (!f) {
    state.SkipWithError(
        "Test strings missing. Googlers: download "
        "go/perfetto-benchmark-slice-strings and save into /tmp/slice_strings");
    return strs;
  }
  char line[4096];
  while (fgets(line, sizeof(line), *f)) {
    strs.emplace_back(base::StringView(line).ToStdString());
  }
  return strs;
}

template <class... Args>
static void BM_Glob(benchmark::State& state, Args&&... args) {
  auto args_tuple = std::make_tuple(std::move(args)...);

  std::vector<std::string> strs = LoadTraceStrings(state);
  GlobMatcher glob = GlobMatcher::FromPattern(std::get<0>(args_tuple));
  for (auto _ : state) {
    for (const std::string& str : strs)
      benchmark::DoNotOptimize(glob.Matches(base::StringView(str)));
    benchmark::ClobberMemory();
  }
  state.counters["str/s"] = Counter(static_cast<double>(strs.size()),
                                    Counter::kIsIterationInvariantRate);
  state.counters["s/str"] =
      Counter(static_cast<double>(strs.size()),
              Counter::kIsIterationInvariantRate | Counter::kInvert);
}

BENCHMARK_CAPTURE(BM_Glob, android, kAndroidGlob);
BENCHMARK_CAPTURE(BM_Glob, launching, kLaunchingGlob);
BENCHMARK_CAPTURE(BM_Glob, choreographer, kChoreographerGlob);
BENCHMARK_CAPTURE(BM_Glob, question_mark, kQuestionMarkGlob);
BENCHMARK_CAPTURE(BM_Glob, char_class, kCharClassGlob);

template <class... Args>
static void BM_SqliteGlob(benchmark::State& state, Args&&... args) {
  auto args_tuple = std::make_tuple(std::move(args)...);
  const char* glob = std::get<0>(args_tuple);

  std::vector<std::string> strs = LoadTraceStrings(state);
  for (auto _ : state) {
    for (const std::string& str : strs)
      benchmark::DoNotOptimize(sqlite3_strglob(glob, str.c_str()));
    benchmark::ClobberMemory();
  }
  state.counters["str/s"] = Counter(static_cast<double>(strs.size()),
                                    Counter::kIsIterationInvariantRate);
  state.counters["s/str"] =
      Counter(static_cast<double>(strs.size()),
              Counter::kIsIterationInvariantRate | Counter::kInvert);
}

BENCHMARK_CAPTURE(BM_SqliteGlob, android, kAndroidGlob);
BENCHMARK_CAPTURE(BM_SqliteGlob, launching, kLaunchingGlob);
BENCHMARK_CAPTURE(BM_SqliteGlob, slice, kChoreographerGlob);
BENCHMARK_CAPTURE(BM_SqliteGlob, question_mark, kQuestionMarkGlob);
BENCHMARK_CAPTURE(BM_SqliteGlob, char_class, kCharClassGlob);

}  // namespace
