// 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 "src/storage/lib/vfs/cpp/pseudo_dir.h"

#include <zircon/syscalls.h>

#include <random>
#include <vector>

#include <fbl/ref_ptr.h>
#include <fbl/string_printf.h>
#include <perftest/perftest.h>

#include "src/lib/fxl/strings/string_printf.h"
#include "src/storage/lib/vfs/cpp/pseudo_file.h"
#include "util.h"

namespace {

// Benchmark baseline creation time.
bool PseudoDirCreateTest(perftest::RepeatState* state) {
  while (state->KeepRunning()) {
    perftest::DoNotOptimize(fbl::MakeRefCounted<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::MakeRefCounted<fs::PseudoDir>();
  auto file = fbl::MakeRefCounted<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::MakeRefCounted<fs::PseudoDir>();
  auto file = fbl::MakeRefCounted<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(file_names[i], &out);
    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::MakeRefCounted<fs::PseudoDir>();
  auto file = fbl::MakeRefCounted<fs::UnbufferedPseudoFile>();

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

  fs::VdirCookie cookie;
  while (state->KeepRunning()) {
    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
