// Copyright 2023 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_F2FS_BITMAP_H_
#define SRC_STORAGE_F2FS_BITMAP_H_

#include <limits.h>
#include <stddef.h>
#include <zircon/types.h>

#include <bitmap/raw-bitmap.h>
#include <bitmap/storage.h>
#include <fbl/macros.h>
#include <fbl/ref_ptr.h>
#include <safemath/checked_math.h>

#include "src/storage/f2fs/common.h"

namespace f2fs {

constexpr size_t kLastNodeMask = 0x7;

using RawBitmap = bitmap::RawBitmapGeneric<bitmap::VmoStorage>;
using RawBitmapHeap = bitmap::RawBitmapGeneric<bitmap::DefaultStorage>;

class Page;
class PageBitmap {
 public:
  PageBitmap() = delete;
  PageBitmap(const PageBitmap &bits) = delete;
  PageBitmap &operator=(const PageBitmap &bits) = delete;
  PageBitmap &operator=(PageBitmap &&bits) = delete;

  PageBitmap(fbl::RefPtr<Page> page, void *bitmap, size_t size);
  PageBitmap(void *bitmap, size_t size);
  PageBitmap(PageBitmap &&bits) = default;

  bool Set(size_t pos);
  bool Clear(size_t pos);
  bool Test(size_t pos) const;
  size_t GetSize() const;

  size_t FindNextZeroBit(size_t pos) const { return FindNextZeroBit(pos, size_); }
  size_t FindNextZeroBit(size_t pos, size_t max_pos) const;
  size_t FindNextBit(size_t pos) const { return FindNextBit(pos, size_); }
  size_t FindNextBit(size_t pos, size_t max_pos) const;

 private:
  uint8_t &GetNode(size_t pos) { return bits_[pos >> kShiftForBitSize]; }
  const uint8_t &GetNode(size_t pos) const { return bits_[pos >> kShiftForBitSize]; }

  fbl::RefPtr<Page> page_;
  uint8_t *const bits_ = nullptr;
  const size_t size_ = 0;
};

template <typename T = uint8_t>
inline T GetMask(const T value, const size_t offset) {
  return static_cast<T>(value << offset);
}

inline size_t GetBitSize(size_t size_in_byte) {
  return safemath::CheckLsh(size_in_byte, kShiftForBitSize).ValueOrDie();
}

inline size_t GetByteSize(size_t num_bits) {
  return CheckedDivRoundUp<size_t>(num_bits, kBitsPerByte);
}

inline size_t ToMsbFirst(size_t offset) {
  size_t index_in_last_node = offset & kLastNodeMask;
  return offset + 7 - 2 * index_in_last_node;
}

// It copies bits from [0, len) of |src| to [offset, offset + len) of |dst|.
// |offset| + |len| and |len| must be multiples of 8.
inline zx_status_t bitcpy(uint8_t *dst, const uint8_t *src, size_t offset, size_t len) {
  size_t end = offset + len;
  size_t start_in_byte = offset / kBitsPerByte;
  size_t end_in_byte = GetByteSize(end);
  if (offset & kLastNodeMask || end & kLastNodeMask || end_in_byte <= start_in_byte) {
    return ZX_ERR_INVALID_ARGS;
  }
  memcpy(dst + start_in_byte, src, end_in_byte - start_in_byte);
  return ZX_OK;
}

template <typename T = RawBitmap>
inline zx_status_t CloneBits(T &to, const T &from, size_t offset, size_t len) {
  if (to.size() < offset + len || from.size() < len) {
    return ZX_ERR_INVALID_ARGS;
  }
  uint8_t *dst = static_cast<uint8_t *>(to.StorageUnsafe()->GetData());
  const uint8_t *src = static_cast<const uint8_t *>(from.StorageUnsafe()->GetData());
  bitcpy(dst, src, offset, len);
  return ZX_OK;
}

template <typename T = RawBitmap>
inline zx_status_t CloneBits(T &to, const void *from, size_t offset, size_t len) {
  if (to.size() < offset + len) {
    return ZX_ERR_INVALID_ARGS;
  }
  uint8_t *dst = static_cast<uint8_t *>(to.StorageUnsafe()->GetData());
  const uint8_t *src = static_cast<const uint8_t *>(from);
  bitcpy(dst, src, offset, len);
  return ZX_OK;
}

template <typename T = RawBitmap>
inline zx_status_t CloneBits(void *to, const T &from, size_t offset, size_t len) {
  if (from.size() < len) {
    return ZX_ERR_INVALID_ARGS;
  }
  uint8_t *dst = static_cast<uint8_t *>(to);
  const uint8_t *src = static_cast<const uint8_t *>(from.StorageUnsafe()->GetData());
  bitcpy(dst, src, offset, len);
  return ZX_OK;
}

size_t CountBits(const RawBitmap &bits, size_t offset, size_t len);

}  // namespace f2fs

#endif  // SRC_STORAGE_F2FS_BITMAP_H_
