// 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.

#ifndef SRC_STORAGE_FS_TEST_FS_TEST_H_
#define SRC_STORAGE_FS_TEST_FS_TEST_H_

#include <fcntl.h>
#include <lib/zx/status.h>
#include <lib/zx/time.h>
#include <stdint.h>
#include <zircon/compiler.h>

#include <functional>
#include <iostream>
#include <limits>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include <fbl/unique_fd.h>
#include <ramdevice-client/ramnand.h>

#include "src/lib/storage/fs_management/cpp/admin.h"
#include "src/lib/storage/fs_management/cpp/format.h"
#include "src/lib/storage/fs_management/cpp/mount.h"
#include "src/storage/blobfs/blob_layout.h"
#include "src/storage/blobfs/compression_settings.h"
#include "src/storage/testing/ram_disk.h"

namespace fs_test {

class Filesystem;

using RamDevice = std::variant<storage::RamDisk, ramdevice_client::RamNand>;

struct TestFilesystemOptions {
  static TestFilesystemOptions DefaultBlobfs();
  static TestFilesystemOptions BlobfsWithoutFvm();

  std::string description;
  bool use_ram_nand = false;
  // If set specifies a VMO to be used to back the device.  If used for ram-nand, Its size must
  // match the device size (if device_block_count is non-zero), including the extra required for
  // OOB.
  zx::unowned_vmo vmo;
  bool use_fvm = false;

  // If non-zero, create a dummy FVM partition which has the effect of moving the location of the
  // partition under test to be at a different offset on the underlying device.
  uint64_t dummy_fvm_partition_size = 0;

  // If true, tests will avoid creating volumes smaller than the size given by
  // device_block_size * device_block_count.
  bool has_min_volume_size = false;
  uint64_t device_block_size = 0;
  uint64_t device_block_count = 0;
  uint64_t fvm_slice_size = 0;
  uint64_t initial_fvm_slice_count = 1;
  // Only supported for blobfs for now.
  uint64_t num_inodes = 0;
  const Filesystem* filesystem = nullptr;
  // By default the ram-disk we create is filled with a non-zero value (so that we don't
  // inadvertently depend on it), but that won't work for very large ram-disks (they will trigger
  // OOMs), in which case they can be zero filled.
  bool zero_fill = false;

  // The format blobfs should store blobs in.
  blobfs::BlobLayoutFormat blob_layout_format = blobfs::BlobLayoutFormat::kCompactMerkleTreeAtEnd;
  // The compression algorithm blobfs should use for new files.
  std::optional<blobfs::CompressionAlgorithm> blob_compression_algorithm = std::nullopt;

  // If using ram_nand, the number of writes after which writes should fail.
  uint32_t fail_after;

  // If true, when the ram-disk is disconnected it will discard random writes performed since the
  // last flush (which is all that any device will guarantee).
  bool ram_disk_discard_random_after_last_flush = false;
};

std::ostream& operator<<(std::ostream& out, const TestFilesystemOptions& options);

std::vector<TestFilesystemOptions> AllTestFilesystems();
// Provides the ability to map and filter all test file systems, using the supplied function.
std::vector<TestFilesystemOptions> MapAndFilterAllTestFilesystems(
    std::function<std::optional<TestFilesystemOptions>(const TestFilesystemOptions&)>);
TestFilesystemOptions OptionsWithDescription(std::string_view description);

// Returns device and device path.
zx::status<std::pair<RamDevice, std::string>> CreateRamDevice(const TestFilesystemOptions& options);

// Returns a handle to a test crypt service.
zx::status<zx::channel> GetCryptService();

// A file system instance is a specific instance created for test purposes.
class FilesystemInstance {
 public:
  FilesystemInstance() = default;
  FilesystemInstance(const FilesystemInstance&) = delete;
  FilesystemInstance& operator=(const FilesystemInstance&) = delete;
  virtual ~FilesystemInstance() = default;

  virtual zx::status<> Format(const TestFilesystemOptions&) = 0;
  virtual zx::status<> Mount(const std::string& mount_path,
                             const fs_management::MountOptions& options) = 0;
  virtual zx::status<> Unmount(const std::string& mount_path);
  virtual zx::status<> Fsck() = 0;

  // Returns path of the device on which the filesystem is created. For filesystem that are not
  // block device based, like memfs, the function returns an error.
  virtual zx::status<std::string> DevicePath() const = 0;
  virtual storage::RamDisk* GetRamDisk() { return nullptr; }
  virtual ramdevice_client::RamNand* GetRamNand() { return nullptr; }
  virtual fidl::UnownedClientEnd<fuchsia_io::Directory> GetOutgoingDirectory() const {
    return fidl::ClientEnd<fuchsia_io::Directory>();
  }
  virtual void ResetOutgoingDirectory() {}
};

// Base class for all supported file systems. It is a factory class that generates
// instances of FilesystemInstance subclasses.
class Filesystem {
 public:
  struct Traits {
    std::string name;
    zx::duration timestamp_granularity = zx::nsec(1);
    bool supports_hard_links = true;
    bool supports_mmap = false;
    bool supports_mmap_shared_write = false;
    bool supports_resize = false;
    int64_t max_file_size = std::numeric_limits<int64_t>::max();
    int64_t max_block_size = std::numeric_limits<int64_t>::max();
    bool in_memory = false;
    bool is_case_sensitive = true;
    bool supports_sparse_files = true;
    bool is_slow = false;
    bool supports_fsck_after_every_transaction = false;
    bool has_directory_size_limit = false;
    bool is_journaled = true;
    bool supports_watch_event_deleted = true;
    bool supports_inspect = false;
    bool supports_shutdown_on_no_connections = false;
    bool uses_crypt = false;
  };

  virtual ~Filesystem() = default;
  virtual zx::status<std::unique_ptr<FilesystemInstance>> Make(
      const TestFilesystemOptions& options) const = 0;
  virtual zx::status<std::unique_ptr<FilesystemInstance>> Open(
      const TestFilesystemOptions& options) const {
    return zx::error(ZX_ERR_NOT_SUPPORTED);
  }
  virtual const Traits& GetTraits() const = 0;
};

// Template that implementations can use to gain the SharedInstance method.
template <typename T>
class FilesystemImpl : public Filesystem {
 public:
  static const T& SharedInstance() {
    static const auto* const kInstance = new T();
    return *kInstance;
  }
};

template <typename T>
class FilesystemImplWithDefaultMake : public FilesystemImpl<T> {
 public:
  virtual std::unique_ptr<FilesystemInstance> Create(RamDevice device,
                                                     std::string device_path) const = 0;

  zx::status<std::unique_ptr<FilesystemInstance>> Make(
      const TestFilesystemOptions& options) const override {
    auto result = CreateRamDevice(options);
    if (result.is_error()) {
      return result.take_error();
    }
    auto [device, device_path] = std::move(result).value();
    auto instance = Create(std::move(device), std::move(device_path));
    zx::status<> status = instance->Format(options);
    if (status.is_error()) {
      return status.take_error();
    }
    return zx::ok(std::move(instance));
  }
};

// -- Default implementations that use fs-management --

zx::status<> FsFormat(const std::string& device_path, fs_management::DiskFormat format,
                      const fs_management::MkfsOptions& options);

zx::status<fidl::ClientEnd<fuchsia_io::Directory>> FsMount(
    const std::string& device_path, const std::string& mount_path, fs_management::DiskFormat format,
    const fs_management::MountOptions& mount_options);

zx::status<std::pair<RamDevice, std::string>> OpenRamDevice(const TestFilesystemOptions& options);

std::string StripTrailingSlash(const std::string& in);

// Removes `mount_path` from the namespace.
zx::status<> FsUnbind(const std::string& mount_path);

}  // namespace fs_test

#endif  // SRC_STORAGE_FS_TEST_FS_TEST_H_
