// Copyright 2025 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_FVM_FVM_TEST_INSTANCE_H_
#define SRC_STORAGE_FVM_FVM_TEST_INSTANCE_H_

#include <fidl/fuchsia.device/cpp/wire.h>
#include <fidl/fuchsia.hardware.block.volume/cpp/wire.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/driver_test_realm/realm_builder/cpp/lib.h>
#include <lib/zx/result.h>

#include <memory>

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

#include "src/storage/lib/fs_management/cpp/fvm.h"

namespace fvm {

enum class FvmImplementation : uint8_t { kDriver, kComponent };

constexpr char kFvmDriverLib[] = "fvm.cm";

constexpr uuid::Uuid kTestUniqueGuid1 = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                                         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
constexpr uuid::Uuid kTestUniqueGuid2 = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
                                         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};

constexpr std::string_view kTestPartDataName = "data";
constexpr uuid::Uuid kTestPartDataGuid = {
    0xAA, 0xFF, 0xBB, 0x00, 0x33, 0x44, 0x88, 0x99, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
};

constexpr std::string_view kTestPartBlobName = "blob";
constexpr uuid::Uuid kTestPartBlobGuid = {
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xAA, 0xFF, 0xBB, 0x00, 0x33, 0x44, 0x88, 0x99,
};

constexpr std::string_view kTestPartSystemName = "system";
constexpr uuid::Uuid kTestPartSystemGuid = {
    0xEE, 0xFF, 0xBB, 0x00, 0x33, 0x44, 0x88, 0x99, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
};

class BlockConnector {
 public:
  virtual ~BlockConnector() = default;

  virtual fidl::ClientEnd<fuchsia_hardware_block::Block> connect_block() const = 0;

  virtual fidl::UnownedClientEnd<fuchsia_hardware_block::Block> as_block() const = 0;

  virtual fidl::UnownedClientEnd<fuchsia_hardware_block_volume::Volume> as_volume() const = 0;
};

struct AllocatePartitionRequest {
  size_t slice_count = 1;
  const uuid::Uuid& type;
  const uuid::Uuid& guid;
  const std::string_view& name;
  uint32_t flags = 0;
};

class FvmInstance {
 public:
  virtual void SetUp() = 0;
  virtual void TearDown() = 0;

  virtual ~FvmInstance() = default;

  // Creates a ramdisk, destroying and recreating it if it already exists.
  virtual void CreateRamdisk(uint64_t block_size, uint64_t block_count) = 0;

  // Creates a ramdisk and formats it with fvm.
  virtual void CreateFvm(uint64_t block_size, uint64_t block_count, uint64_t slice_size) = 0;

  virtual void StartFvm() = 0;

  // Rebinds or restarts the FVM instance.
  virtual void RestartFvm() = 0;

  // Create a new ramdisk with a new total size. The block size must be the same as the existing
  // block size. This will start the disk and the fvm after recreating the disk.
  virtual void RestartFvmWithNewDiskSize(uint64_t block_size, uint64_t block_count) = 0;

  // Get general info about fvm.
  virtual fuchsia_hardware_block_volume::wire::VolumeManagerInfo GetFvmInfo() const = 0;

  // Allocates a new partition.
  virtual zx::result<std::unique_ptr<BlockConnector>> AllocatePartition(
      const AllocatePartitionRequest& request) const = 0;

  // Opens an existing partition. This will wait for it to appear if it doesn't already exist.
  virtual zx::result<std::unique_ptr<BlockConnector>> OpenPartition(
      std::string_view label) const = 0;

  // Destroys the named partition, removing it from this fvm instance.
  virtual void DestroyPartition(std::string_view label) const = 0;

  // Returns the block interface of the underlying ramdisk.
  virtual fidl::ClientEnd<fuchsia_hardware_block::Block> GetRamdiskPartition() const = 0;
};

class DriverFvmInstance : public FvmInstance {
 public:
  void SetUp() override;
  void TearDown() override;
  void CreateRamdisk(uint64_t block_size, uint64_t block_count) override;
  void CreateFvm(uint64_t block_size, uint64_t block_count, uint64_t slice_size) override;
  void StartFvm() override;
  void RestartFvm() override;
  void RestartFvmWithNewDiskSize(uint64_t block_size, uint64_t block_count) override;
  fuchsia_hardware_block_volume::wire::VolumeManagerInfo GetFvmInfo() const override;
  zx::result<std::unique_ptr<BlockConnector>> AllocatePartition(
      const AllocatePartitionRequest& request) const override;
  zx::result<std::unique_ptr<BlockConnector>> OpenPartition(std::string_view label) const override;
  void DestroyPartition(std::string_view label) const override;
  fidl::ClientEnd<fuchsia_hardware_block::Block> GetRamdiskPartition() const override;

  fidl::UnownedClientEnd<fuchsia_device::Controller> GetRamdiskControllerInterface() const;
  const fbl::unique_fd& devfs_root() const { return devfs_root_; }
  zx::result<fidl::ClientEnd<fuchsia_hardware_block_volume::VolumeManager>> GetVolumeManager()
      const;
  zx::result<std::unique_ptr<BlockConnector>> OpenPartitionNoWait(std::string_view label) const;
  std::string GetFvmPath() const;

 private:
  std::unique_ptr<async::Loop> loop_;
  std::unique_ptr<component_testing::RealmRoot> realm_;
  fbl::unique_fd devfs_root_;
  ramdevice_client::Ramdisk ramdisk_;
  zx::vmo vmo_;
};

std::unique_ptr<FvmInstance> CreateFvmInstance(FvmImplementation impl);

}  // namespace fvm

#endif  // SRC_STORAGE_FVM_FVM_TEST_INSTANCE_H_
