// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <random>
#include <vector>

#include <fbl/ref_ptr.h>
#include <fbl/string_printf.h>
#include <fs/pseudo-dir.h>
#include <fs/pseudo-file.h>
#include <src/lib/fxl/strings/string_printf.h>
#include <perftest/perftest.h>
#include <zircon/syscalls.h>

#include "util.h"

namespace {

// Benchmark baseline creation time.
bool PseudoDirCreateTest(perftest::RepeatState* state) {
  while (state->KeepRunning()) {
    perftest::DoNotOptimize(fs::PseudoDir());
  }
  return true;
}

// Benchmark the time to remove an existing entry and add it back.
// Parameterized by the number of files.
bool PseudoDirRemoveAddTest(perftest::RepeatState* state, int file_count) {
  auto file_names = util::MakeDeterministicNamesList(file_count);

  auto dir = fbl::AdoptRef(new fs::PseudoDir());
  auto file = fbl::AdoptRef(new fs::UnbufferedPseudoFile());

  for (const auto& name : file_names) {
    dir->AddEntry(name, file);
  }

  int i = 0;

  while (state->KeepRunning()) {
    dir->RemoveEntry(file_names[i]);
    dir->AddEntry(file_names[i], file);
    i = (i + 1) % file_names.size();
  }
  return true;
}

// Benchmark the time to lookup an existing entry.
// Parameterized by the number of files.
bool PseudoDirLookupTest(perftest::RepeatState* state, int file_count) {
  auto file_names = util::MakeDeterministicNamesList(file_count);

  auto dir = fbl::AdoptRef(new fs::PseudoDir());
  auto file = fbl::AdoptRef(new fs::UnbufferedPseudoFile());

  for (const auto& name : file_names) {
    dir->AddEntry(name, file);
  }

  int i = 0;
  fbl::RefPtr<fs::Vnode> out;

  while (state->KeepRunning()) {
    dir->Lookup(&out, file_names[i]);
    i = (i + 1) % file_names.size();
  }
  return true;
}

// Benchmark the time to read out a directory.
// Parameterized by the number of files and the size of the output buffer.
bool PseudoDirReaddirTest(perftest::RepeatState* state, int file_count,
                          int buffer_size) {
  auto file_names = util::MakeDeterministicNamesList(file_count);
  std::vector<char> buffer(buffer_size);

  auto dir = fbl::AdoptRef(new fs::PseudoDir());
  auto file = fbl::AdoptRef(new fs::UnbufferedPseudoFile());

  for (const auto& name : file_names) {
    dir->AddEntry(name, file);
  }

  while (state->KeepRunning()) {
    fs::vdircookie_t cookie;
    size_t real_len = 0;
    do {
      auto status =
          dir->Readdir(&cookie, buffer.data(), buffer.size(), &real_len);
      ZX_DEBUG_ASSERT(ZX_OK == status);
    } while (real_len > 0);
  }
  return true;
}

void RegisterTests() {
  perftest::RegisterTest("PseudoDir/Create", PseudoDirCreateTest);

  for (int file_count = 1; file_count <= 1 << 14; file_count *= 8) {
    auto name = fbl::StringPrintf("PseudoDir/RemoveAdd/%d", file_count);
    perftest::RegisterTest(name.c_str(), PseudoDirRemoveAddTest, file_count);
  }

  for (int file_count = 1; file_count <= 1 << 14; file_count *= 8) {
    auto name = fbl::StringPrintf("PseudoDir/Lookup/%d", file_count);
    perftest::RegisterTest(name.c_str(), PseudoDirLookupTest, file_count);
  }

  for (int buffer_size = 1; buffer_size <= 64; buffer_size *= 8) {
    for (int file_count = 1; file_count <= 1 << 14; file_count *= 8) {
      auto name = fbl::StringPrintf("PseudoDir/Readdir/%d/%dk", file_count,
                                    buffer_size);
      perftest::RegisterTest(name.c_str(), PseudoDirReaddirTest, file_count,
                             buffer_size * 1024);
    }
  }
}

PERFTEST_CTOR(RegisterTests);

}  // namespace
