// Copyright 2020 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 <fcntl.h>
#include <unistd.h>

#include <iostream>
#include <optional>
#include <string>
#include <thread>
#include <vector>

#include <fbl/unique_fd.h>

#include "src/storage/fs_test/fs_test_fixture.h"

namespace fs_test {
namespace {

using DirectoryMaxTest = FilesystemTest;

// Hopefully not pushing against any 'max file length' boundaries, but large enough to fill a
// directory quickly.
constexpr int kLargePathLength = 128;

TEST_P(DirectoryMaxTest, Max) {
  // Write the maximum number of files to a directory
  const std::string dir = "dir/";
  ASSERT_EQ(mkdir(GetPath(dir).c_str(), 0777), 0);

  class Context {
   public:
    explicit Context(std::string prefix) : path_prefix_(std::move(prefix)) {}

    void fill() {
      for (;; ++cnt_) {
        const std::string path = path_prefix_ + std::to_string(cnt_);
        fbl::unique_fd fd(open(path.c_str(), O_RDWR | O_CREAT | O_EXCL, 0644));
        if (!fd) {
          break;
        }
      }
    }

    void unlink_all() {
      for (cnt_ -= cnt_; cnt_ >= 0; cnt_--) {
        const std::string path = path_prefix_ + std::to_string(cnt_);
        int r = unlink(path.c_str());
        if (r != 0) {
          err_ = true;
          break;
        }
      }
    }

    bool err() const { return err_; }
    int count() const { return cnt_; }

   private:
    std::string path_prefix_;
    int cnt_ = 0;
    bool err_ = false;
  };

  const std::string path_prefix = GetPath(dir + std::string(kLargePathLength, '.'));
  std::vector<Context> contexts;
  for (int i = 0; i < 16; i++) {
    contexts.emplace_back(Context(path_prefix + std::to_string(i) + "_"));
  }

  std::vector<std::thread> fillers;
  for (auto& context : contexts) {
    fillers.emplace_back(std::thread([&context]() { context.fill(); }));
  }
  for (auto& thread : fillers) {
    thread.join();
  }

  int total_files = 0;
  for (const auto& context : contexts) {
    total_files += context.count();
  }
  std::cerr << "Wrote a total of " << total_files << "." << std::endl;

  std::cerr << "Starting unmount." << std::endl;
  EXPECT_EQ(fs().Unmount().status_value(), ZX_OK);
  std::cerr << "Starting fsck." << std::endl;
  EXPECT_EQ(fs().Fsck().status_value(), ZX_OK);
  std::cerr << "Starting mount." << std::endl;
  EXPECT_EQ(fs().Mount().status_value(), ZX_OK);

  std::cerr << "Time to clean up." << std::endl;

  std::vector<std::thread> unlinkers;
  for (auto& context : contexts) {
    unlinkers.emplace_back(std::thread([&context]() { context.unlink_all(); }));
  }
  for (auto& thread : unlinkers) {
    thread.join();
  }
  for (auto& context : contexts) {
    ASSERT_FALSE(context.err());
  }
  std::cerr << "Done." << std::endl;
}

INSTANTIATE_TEST_SUITE_P(
    /*no prefix*/, DirectoryMaxTest,
    testing::ValuesIn(MapAndFilterAllTestFilesystems(
        [](TestFilesystemOptions options) -> std::optional<TestFilesystemOptions> {
          // Filesystems such as memfs cannot run this test because they OOM (as expected, given
          // memory is the limiting factor).
          if (options.filesystem->GetTraits().in_memory)
            return std::nullopt;
          if (!options.filesystem->GetTraits().has_directory_size_limit &&
              !options.has_min_volume_size) {
            // Fatfs is slow and, other than the root directory on FAT12/16, is limited by the size
            // of the ram-disk rather than a directory size limit, so use a small ram-disk to keep
            // run-time reasonable, and do the same for other filesystems that don't have a
            // directory size limit.
            options.device_block_count = options.filesystem->GetTraits().is_slow ? 256 : 4096;
          }
          return options;
        })),
    testing::PrintToStringParamName());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DirectoryMaxTest);

}  // namespace
}  // namespace fs_test
