// 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 = 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 = fidl::WireCall<fio::DirectoryAdmin>(caller.channel()).QueryFilesystem();
    ASSERT_EQ(query_result.status(), ZX_OK);
    ASSERT_NE(query_result.Unwrap()->info, nullptr);
    fio::wire::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
