// 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 <zircon/syscalls.h>

#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 <perftest/perftest.h>

#include "src/lib/fxl/strings/string_printf.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(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::AdoptRef(new fs::PseudoDir());
  auto file = fbl::AdoptRef(new 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
