// Copyright 2017 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 <errno.h>
#include <fcntl.h>
#include <fuchsia/io/llcpp/fidl.h>
#include <lib/fdio/cpp/caller.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/errors.h>

#include <iostream>
#include <string>
#include <tuple>
#include <vector>

#include <fbl/unique_fd.h>

#include "src/storage/fs_test/fs_test_fixture.h"
#include "src/storage/fvm/format.h"
#include "src/storage/minfs/format.h"

namespace fs_test {
namespace {

namespace fio = ::llcpp::fuchsia::io;

using ParamType = std::tuple<TestFilesystemOptions, /*remount=*/bool>;

class ResizeTest : public BaseFilesystemTest, public testing::WithParamInterface<ParamType> {
 public:
  ResizeTest() : BaseFilesystemTest(std::get<0>(GetParam())) {}

  bool ShouldRemount() const { return std::get<1>(GetParam()); }

 protected:
  void QueryInfo(uint64_t* out_free_pool_size) {
    fbl::unique_fd fd(open(fs().mount_path().c_str(), O_RDONLY | O_DIRECTORY));
    ASSERT_TRUE(fd);
    fdio_cpp::FdioCaller caller(std::move(fd));
    auto query_result = fio::DirectoryAdmin::Call::QueryFilesystem(caller.channel());
    ASSERT_EQ(query_result.status(), ZX_OK);
    ASSERT_NE(query_result.Unwrap()->info, nullptr);
    fio::FilesystemInfo* info = query_result.Unwrap()->info.get();
    // This should always be true, for all filesystems.
    ASSERT_GT(info->total_bytes, info->used_bytes);
    *out_free_pool_size = info->free_shared_pool_bytes;
  }

  void EnsureCanGrow() {
    uint64_t free_pool_size;
    ASSERT_NO_FATAL_FAILURE(QueryInfo(&free_pool_size));
    // This tests expects to run with free FVM space.
    ASSERT_GT(free_pool_size, 0ul);
  }

  void EnsureCannotGrow() {
    uint64_t free_pool_size;
    ASSERT_NO_FATAL_FAILURE(QueryInfo(&free_pool_size));
    ASSERT_EQ(free_pool_size, 0ul);
  }
};

using MaxInodeTest = ResizeTest;

TEST_P(MaxInodeTest, UseAllInodes) {
  ASSERT_NO_FATAL_FAILURE(EnsureCanGrow());

  // Create 100,000 inodes.
  // We expect that this will force enough inodes to cause the
  // filesystem structures to resize partway through.
  constexpr size_t kFilesPerDirectory = 100;
  size_t d = 0;
  while (true) {
    if (d % 100 == 0) {
      std::cout << "Creating directory (containing 100 files): " << d << std::endl;
    }
    const std::string dname = GetPath(std::to_string(d));
    if (mkdir(dname.c_str(), 0666) < 0) {
      ASSERT_EQ(errno, ENOSPC);
      break;
    }
    bool stop = false;
    for (size_t f = 0; f < kFilesPerDirectory; f++) {
      const std::string fname = dname + "/" + std::to_string(f);
      fbl::unique_fd fd(open(fname.c_str(), O_CREAT | O_RDWR | O_EXCL));
      if (!fd) {
        ASSERT_EQ(errno, ENOSPC);
        stop = true;
        break;
      }
    }
    if (stop) {
      break;
    }
    d++;
  }

  ASSERT_NO_FATAL_FAILURE(EnsureCannotGrow());

  if (ShouldRemount()) {
    std::cout << "Unmounting, Verifying, Re-mounting..." << std::endl;
    EXPECT_EQ(fs().Unmount().status_value(), ZX_OK);
    EXPECT_EQ(fs().Fsck().status_value(), ZX_OK);
    EXPECT_EQ(fs().Mount().status_value(), ZX_OK);
  }

  size_t directory_count = d;
  for (size_t d = 0; d < directory_count; d++) {
    if (d % 100 == 0) {
      std::cout << "Deleting directory (containing 100 files): " << d << std::endl;
    }
    const std::string dname = GetPath(std::to_string(d));
    for (size_t f = 0; f < kFilesPerDirectory; f++) {
      const std::string fname = dname + "/" + std::to_string(f);
      ASSERT_EQ(unlink(fname.c_str()), 0);
    }
    ASSERT_EQ(rmdir(dname.c_str()), 0);
  }
}

using MaxDataTest = ResizeTest;

TEST_P(MaxDataTest, UseAllData) {
  constexpr size_t kBufSize = 1 << 20;
  constexpr size_t kFileSize = 20 * kBufSize;
  ASSERT_NO_FATAL_FAILURE(EnsureCanGrow());

  uint64_t disk_size = fs().options().device_block_count * fs().options().device_block_size;
  // Counts both copies of the metadata.
  // TODO(jfsulliv) change to use MetadataBuffer::BytesNeeded() when that's landed.
  size_t metadata_size =
      fvm::Header::FromDiskSize(fvm::kMaxUsablePartitions, disk_size, fs().options().fvm_slice_size)
          .GetDataStartOffset();

  ASSERT_GT(disk_size, metadata_size);
  disk_size -= metadata_size;

  ASSERT_GT(disk_size, minfs::kMinfsMinimumSlices * fs().options().fvm_slice_size);
  disk_size -= minfs::kMinfsMinimumSlices * fs().options().fvm_slice_size;

  std::vector<uint8_t> buf(kBufSize);

  size_t f = 0;
  while (true) {
    std::cout << "Creating 20 MB file " << f << std::endl;
    const std::string fname = GetPath(std::to_string(f));
    fbl::unique_fd fd(open(fname.c_str(), O_CREAT | O_RDWR | O_EXCL));
    if (!fd) {
      ASSERT_EQ(errno, ENOSPC);
      break;
    }
    f++;
    bool stop = false;
    ASSERT_EQ(ftruncate(fd.get(), kFileSize), 0);
    for (size_t done = 0; done < kFileSize;) {
      ssize_t r = write(fd.get(), buf.data(), std::min(kBufSize, kFileSize - done));
      if (r < 0) {
        ASSERT_EQ(errno, ENOSPC);
        stop = true;
        break;
      }
      done += r;
    }
    if (stop) {
      break;
    }
  }

  ASSERT_NO_FATAL_FAILURE(EnsureCannotGrow());

  if (ShouldRemount()) {
    std::cout << "Unmounting, Verifying, Re-mounting..." << std::endl;
    EXPECT_EQ(fs().Unmount().status_value(), ZX_OK);
    EXPECT_EQ(fs().Fsck().status_value(), ZX_OK);
    EXPECT_EQ(fs().Mount().status_value(), ZX_OK);
  }

  size_t file_count = f;
  for (size_t f = 0; f < file_count; f++) {
    const std::string fname = GetPath(std::to_string(f));
    ASSERT_EQ(unlink(fname.c_str()), 0);
  }
}

std::string GetParamDescription(const testing::TestParamInfo<ParamType>& param) {
  std::stringstream s;
  s << std::get<0>(param.param) << (std::get<1>(param.param) ? "WithRemount" : "WithoutRemount");
  return s.str();
}

std::vector<ParamType> GetTestCombinationsForMaxInodeTest() {
  std::vector<ParamType> test_combinations;
  for (TestFilesystemOptions options : AllTestFilesystems()) {
    if (options.use_fvm && options.filesystem->GetTraits().supports_resize) {
      options.device_block_count = 1LLU << 15;
      options.device_block_size = 1LLU << 9;
      options.fvm_slice_size = 1LLU << 20;
      test_combinations.push_back(ParamType{options, false});
      if (options.filesystem->GetTraits().can_unmount) {
        test_combinations.push_back(ParamType{options, true});
      }
    }
  }
  return test_combinations;
}

std::vector<ParamType> GetTestCombinationsForMaxDataTest() {
  std::vector<ParamType> test_combinations;
  for (TestFilesystemOptions options : AllTestFilesystems()) {
    if (options.use_fvm && options.filesystem->GetTraits().supports_resize) {
      options.device_block_count = 1LLU << 17;
      options.device_block_size = 1LLU << 9;
      options.fvm_slice_size = 1LLU << 20;
      test_combinations.push_back(ParamType{options, false});
      if (options.filesystem->GetTraits().can_unmount) {
        test_combinations.push_back(ParamType{options, true});
      }
    }
  }
  return test_combinations;
}

INSTANTIATE_TEST_SUITE_P(/*no prefix*/, MaxInodeTest,
                         testing::ValuesIn(GetTestCombinationsForMaxInodeTest()),
                         GetParamDescription);

INSTANTIATE_TEST_SUITE_P(/*no prefix*/, MaxDataTest,
                         testing::ValuesIn(GetTestCombinationsForMaxDataTest()),
                         GetParamDescription);

}  // namespace
}  // namespace fs_test
