// Copyright 2019 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_MINFS_ALLOCATOR_METADATA_H_
#define SRC_STORAGE_MINFS_ALLOCATOR_METADATA_H_

#include <bitmap/storage.h>
#include <fbl/function.h>
#include <fbl/macros.h>

#include "src/storage/minfs/format.h"
#include "src/storage/minfs/superblock.h"

namespace minfs {

// This structure contains pointers to relevant allocator fields in the superblock.
struct SuperblockAllocatorAccess {
  uint32_t Superblock::*used;
  uint32_t Superblock::*total;
  uint32_t Superblock::*data_slices;
  uint32_t Superblock::*metadata_slices;

  // Returns pointers suitable for the block allocator.
  static SuperblockAllocatorAccess Blocks() {
    return SuperblockAllocatorAccess{&Superblock::alloc_block_count, &Superblock::block_count,
                                     &Superblock::dat_slices, &Superblock::abm_slices};
  }

  // Returns pointers suitable for the inode allocator.
  static SuperblockAllocatorAccess Inodes() {
    return SuperblockAllocatorAccess{&Superblock::alloc_inode_count, &Superblock::inode_count,
                                     &Superblock::ino_slices, &Superblock::ibm_slices};
  }
};

// Represents the FVM-related information for the allocator, including
// slice usage and a mechanism to grow the allocation pool.
class AllocatorFvmMetadata {
 public:
  AllocatorFvmMetadata() = default;
  AllocatorFvmMetadata(SuperblockManager* superblock, SuperblockAllocatorAccess access)
      : superblock_(superblock), superblock_access_(access) {}

  // Movable, not copyable.
  AllocatorFvmMetadata(AllocatorFvmMetadata&&) = default;
  AllocatorFvmMetadata& operator=(AllocatorFvmMetadata&&) = default;

  uint32_t UnitsPerSlices(uint32_t slice, uint32_t unit_size) const;
  uint32_t SlicesToBlocks(uint32_t slices) const;
  uint32_t BlocksToSlices(uint32_t blocks) const;

  uint32_t DataSlices() const { return superblock_->Info().*superblock_access_.data_slices; }

  void SetDataSlices(uint32_t slices) {
    superblock_->MutableInfo()->*superblock_access_.data_slices = slices;
  }

  uint32_t MetadataSlices() const {
    return superblock_->Info().*superblock_access_.metadata_slices;
  }

  void SetMetadataSlices(uint32_t slices) {
    superblock_->MutableInfo()->*superblock_access_.metadata_slices = slices;
  }

  uint64_t SliceSize() const { return superblock_->Info().slice_size; }

 private:
  SuperblockManager* superblock_ = nullptr;
  SuperblockAllocatorAccess superblock_access_ = {};
};

// Metadata information used to initialize a generic allocator.
//
// This structure contains references to the global superblock,
// for fields that are intended to be updated.
//
// The allocator is the sole mutator of these fields while the
// filesystem is mounted.
class AllocatorMetadata {
 public:
  AllocatorMetadata() = default;
  AllocatorMetadata(blk_t data_start_block, blk_t metadata_start_block, bool using_fvm,
                    AllocatorFvmMetadata fvm, SuperblockManager* superblock_manager,
                    SuperblockAllocatorAccess interface);

  // Movable, not copyable.
  AllocatorMetadata(AllocatorMetadata&&) = default;
  AllocatorMetadata& operator=(AllocatorMetadata&&) = default;

  blk_t DataStartBlock() const { return data_start_block_; }

  blk_t MetadataStartBlock() const { return metadata_start_block_; }

  bool UsingFvm() const { return using_fvm_; }

  AllocatorFvmMetadata& Fvm() {
    ZX_DEBUG_ASSERT(UsingFvm());
    return fvm_;
  }

  uint32_t PoolUsed() const { return superblock_->Info().*superblock_access_.used; }

  // Return the number of elements which are still available for allocation/reservation.
  uint32_t PoolAvailable() const { return PoolTotal() - PoolUsed(); }

  void PoolAllocate(uint32_t units) {
    ZX_DEBUG_ASSERT_MSG(PoolTotal() - PoolUsed() >= units, "total=%u, used=%u, units=%u\n",
                        PoolTotal(), PoolUsed(), units);
    superblock_->MutableInfo()->*superblock_access_.used += units;
  }

  void PoolRelease(uint32_t units) {
    ZX_DEBUG_ASSERT_MSG(PoolUsed() >= units, "used=%u, units=%u\n", PoolUsed(), units);
    superblock_->MutableInfo()->*superblock_access_.used -= units;
  }

  uint32_t PoolTotal() const { return superblock_->Info().*superblock_access_.total; }

  void SetPoolTotal(uint32_t total) {
    superblock_->MutableInfo()->*superblock_access_.total = total;
  }

 private:
  // Block at which data for the allocator starts.
  blk_t data_start_block_;

  // Block at which metadata for the allocator starts.
  blk_t metadata_start_block_;

  // This metadata is only valid if the Allocator is using an FVM.
  bool using_fvm_;
  AllocatorFvmMetadata fvm_;

  SuperblockManager* superblock_ = nullptr;
  SuperblockAllocatorAccess superblock_access_ = {};
};

}  // namespace minfs

#endif  // SRC_STORAGE_MINFS_ALLOCATOR_METADATA_H_
