// 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_MINFS_BLOCK_UTILS_H_
#define SRC_STORAGE_MINFS_BLOCK_UTILS_H_

#include <lib/zx/status.h>

#include <range/range.h>

namespace minfs {

using ByteRange = range::Range<uint64_t>;
using BlockRange = range::Range<uint64_t>;

// Represents a block on a device. The block should be relative to the start of the device, and the
// block size is that used by the file system. The block can also be unmapped a.k.a. sparse. Files
// that are unmapped blocks are zeroed; they occupy no space on the disk, but the user sees zeroed
// data.
class DeviceBlock {
 public:
  static DeviceBlock Unmapped() { return {}; }

  DeviceBlock() = default;
  DeviceBlock(uint64_t block) : block_(block) { ZX_ASSERT(block != kUnmapped); }

  DeviceBlock(const DeviceBlock& other) = default;
  DeviceBlock& operator=(const DeviceBlock& other) = default;

  bool IsMapped() const { return block_ != kUnmapped; }
  uint64_t block() const {
    ZX_ASSERT(block_ != kUnmapped);
    return block_;
  }

  bool operator==(const DeviceBlock& other) const { return block_ == other.block_; }
  bool operator!=(const DeviceBlock& other) const { return block_ != other.block_; }

 private:
  static constexpr uint64_t kUnmapped = std::numeric_limits<uint64_t>::max();

  uint64_t block_ = kUnmapped;
};

class DeviceBlockRange {
 public:
  DeviceBlockRange() = default;
  DeviceBlockRange(DeviceBlock device_block, uint64_t count)
      : device_block_(device_block), count_(count) {}

  DeviceBlockRange(const DeviceBlockRange& other) = default;
  DeviceBlockRange& operator=(const DeviceBlockRange& other) = default;

  DeviceBlock device_block() const { return device_block_; }
  bool IsMapped() const { return device_block_.IsMapped(); }
  uint64_t block() const { return device_block_.block(); }
  uint64_t count() const { return count_; }

 private:
  DeviceBlock device_block_;
  uint64_t count_ = 0;
};

// Given a byte range, returns a block range that covers the byte range.
static inline BlockRange BytesToBlocks(ByteRange range, unsigned block_size) {
  return BlockRange(range.Start() / block_size, (range.End() + block_size - 1) / block_size);
}

// Helpers that will call |callback| for all the blocks that encompass the range, which
// is in blocks. |callback| is of the form:
//
//   zx::status<uint64_t> callback(range::Range<BlockType> range);
//
// |callback| can modify |block_count| to indicate how many blocks it processed if less than all of
// the blocks, or leave it unchanged if all blocks are processed.
template <typename BlockType, typename F>
[[nodiscard]] zx_status_t EnumerateBlocks(range::Range<BlockType> range, F callback) {
  uint64_t len;
  BlockType block = range.Start();
  for (; block < range.End(); block += len) {
    zx::status<uint64_t> status = callback(range::Range(block, range.End()));
    if (status.is_error())
      return status.status_value();
    len = status.value();
    ZX_DEBUG_ASSERT(len > 0);
  }
  return ZX_OK;
}

// Same, but for bytes rather than blocks. It will enumerate all blocks touched by the range.
template <typename F>
[[nodiscard]] zx_status_t EnumerateBlocks(ByteRange range, unsigned block_size, F callback) {
  if (range.Length() == 0)
    return ZX_OK;
  return EnumerateBlocks(BytesToBlocks(range, block_size), callback);
}

}  // namespace minfs

#endif  // SRC_STORAGE_MINFS_BLOCK_UTILS_H_
