// Copyright 2021 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 THIRD_PARTY_F2FS_F2FS_INTERNAL_H_
#define THIRD_PARTY_F2FS_F2FS_INTERNAL_H_

namespace f2fs {

class VnodeF2fs;

// For checkpoint manager
enum class MetaBitmap { kNatBitmap, kSitBitmap };

// for the list of orphan inodes
struct OrphanInodeEntry {
  list_node_t list;  // list head
  nid_t ino = 0;     // inode number
};

// for the list of directory inodes
struct DirInodeEntry {
  list_node_t list;            // list head
  VnodeF2fs *vnode = nullptr;  // vfs inode pointer
};

// for the list of fsync inodes, used only during recovery
struct FsyncInodeEntry {
  list_node_t list;                        // list head
  fbl::RefPtr<VnodeF2fs> vnode = nullptr;  // vfs inode pointer
  block_t blkaddr = 0;                     // block address locating the last inode
};

inline int NatsInCursum(SummaryBlock *sum) { return LeToCpu(sum->n_nats); }
inline int SitsInCursum(SummaryBlock *sum) { return LeToCpu(sum->n_sits); }

inline RawNatEntry NatInJournal(SummaryBlock *sum, int i) { return sum->nat_j.entries[i].ne; }
inline void SetNatInJournal(SummaryBlock *sum, int i, RawNatEntry raw_ne) {
  sum->nat_j.entries[i].ne = raw_ne;
}
inline nid_t NidInJournal(SummaryBlock *sum, int i) { return sum->nat_j.entries[i].nid; }
inline void SetNidInJournal(SummaryBlock *sum, int i, nid_t nid) {
  sum->nat_j.entries[i].nid = nid;
}

inline SitEntry *SitInJournal(SummaryBlock *sum, int i) { return &sum->sit_j.entries[i].se; }
inline uint32_t SegnoInJournal(SummaryBlock *sum, int i) { return sum->sit_j.entries[i].segno; }
inline void SetSegnoInJournal(SummaryBlock *sum, int i, uint32_t segno) {
  sum->sit_j.entries[i].segno = segno;
}

static inline int UpdateNatsInCursum(SummaryBlock *rs, int i) {
  int before = NatsInCursum(rs);
  rs->n_nats = CpuToLe(static_cast<uint32_t>(before + i));
  return before;
}

static inline int UpdateSitsInCursum(SummaryBlock *rs, int i) {
  int before = SitsInCursum(rs);
  rs->n_sits = CpuToLe(static_cast<uint32_t>(before + i));
  return before;
}

// For INODE and NODE manager
constexpr int kXattrNodeOffset = -1;
// store xattrs to one node block per
// file keeping -1 as its node offset to
// distinguish from index node blocks.
constexpr int kRdOnlyNode = 1;
// specify a read-only mode when getting
// a node block. 0 is read-write mode.
// used by GetDnodeOfData().
constexpr int kLinkMax = 32000;  // maximum link count per file

// for in-memory extent cache entry
struct ExtentInfo {
  fs::SharedMutex ext_lock;  // rwlock for consistency
  uint64_t fofs = 0;         // start offset in a file
  uint32_t blk_addr = 0;     // start block address of the extent
  uint64_t len = 0;          // lenth of the extent
};

// i_advise uses Fadvise:xxx bit. We can add additional hints later.
enum class FAdvise {
  kCold = 1,
};

struct InodeInfo {
  uint32_t i_flags = 0;          // keep an inode flags for ioctl
  uint8_t i_advise = 0;          // use to give file attribute hints
  uint64_t i_current_depth = 0;  // use only in directory structure
  umode_t i_acl_mode = 0;        // keep file acl mode temporarily

  uint32_t flags = 0;         // use to pass per-file flags
  uint64_t data_version = 0;  // lastest version of data for fsync
  atomic_t dirty_dents;       // # of dirty dentry pages
  f2fs_hash_t chash;          // hash value of given file name
  uint64_t clevel = 0;        // maximum level of given file name
  nid_t i_xattr_nid = 0;      // node id that contains xattrs
  ExtentInfo ext;             // in-memory extent cache entry
};

struct NmInfo {
  block_t nat_blkaddr = 0;  // base disk address of NAT
  nid_t max_nid = 0;        // maximum possible node ids
  nid_t init_scan_nid = 0;  // the first nid to be scanned
  nid_t next_scan_nid = 0;  // the next nid to be scanned

  // NAT cache management
  RadixTreeRoot nat_root;         // root of the nat entry cache
  fs::SharedMutex nat_tree_lock;  // protect nat_tree_lock
  uint32_t nat_cnt = 0;           // the # of cached nat entries
  list_node_t nat_entries;        // cached nat entry list (clean)
  list_node_t dirty_nat_entries;  // cached nat entry list (dirty)

  // free node ids management
  list_node_t free_nid_list;           // a list for free nids
  fs::SharedMutex free_nid_list_lock;  // protect free nid list
  uint64_t fcnt = 0;                   // the number of free node id
  fbl::Mutex build_lock;               // lock for build free nids

  // for checkpoint
  char *nat_bitmap = nullptr;       // NAT bitmap pointer
  char *nat_prev_bitmap = nullptr;  // JY: NAT previous checkpoint bitmap pointer
  int bitmap_size = 0;              // bitmap size
};

// this structure is used as one of function parameters.
// all the information are dedicated to a given direct node block determined
// by the data offset in a file.
struct DnodeOfData {
  // inode *inode;		// vfs inode pointer
  VnodeF2fs *vnode = nullptr;
  Page *inode_page = nullptr;      // its inode page, NULL is possible
  Page *node_page = nullptr;       // cached direct node page
  nid_t nid = 0;                   // node id of the direct node block
  uint64_t ofs_in_node = 0;        // data offset in the node page
  bool inode_page_locked = false;  // inode page is locked or not
  block_t data_blkaddr = 0;        // block address of the node block
};

static inline void SetNewDnode(DnodeOfData *dn, VnodeF2fs *vnode, Page *ipage, Page *npage,
                               nid_t nid) {
  dn->vnode = vnode;
  dn->inode_page = ipage;
  dn->node_page = npage;
  dn->nid = nid;
  dn->inode_page_locked = 0;
}

// For SIT manager
//
// By default, there are 6 active log areas across the whole main area.
// When considering hot and cold data separation to reduce cleaning overhead,
// we split 3 for data logs and 3 for node logs as hot, warm, and cold types,
// respectively.
// In the current design, you should not change the numbers intentionally.
// Instead, as a mount option such as active_logs=x, you can use 2, 4, and 6
// logs individually according to the underlying devices. (default: 6)
// Just in case, on-disk layout covers maximum 16 logs that consist of 8 for
// data and 8 for node logs.
constexpr int kNrCursegDataType = 3;
constexpr int kNrCursegNodeType = 3;
constexpr int kNrCursegType = kNrCursegDataType + kNrCursegNodeType;

enum class CursegType {
  kCursegHotData = 0,  // directory entry blocks
  kCursegWarmData,     // data blocks
  kCursegColdData,     // multimedia or GCed data blocks
  kCursegHotNode,      // direct node blocks of directory files
  kCursegWarmNode,     // direct node blocks of normal files
  kCursegColdNode,     // indirect node blocks
  kNoCheckType
};

struct SmInfo {
  struct SitInfo *SitInfo = nullptr;              // whole segment information
  struct FreeSegmapInfo *free_info = nullptr;     // free segment information
  struct DirtySeglistInfo *dirty_info = nullptr;  // dirty segment information
  struct CursegInfo *curseg_array = nullptr;      // active segment information

  block_t seg0_blkaddr = 0;  // block address of 0'th segment
  block_t main_blkaddr = 0;  // start block address of main area
  block_t ssa_blkaddr = 0;   // start block address of SSA area

  uint64_t segment_count = 0;      // total # of segments
  uint64_t main_segments = 0;      // # of segments in main area
  uint64_t reserved_segments = 0;  // # of reserved segments
  uint64_t ovp_segments = 0;       // # of overprovision segments
};

// For directory operation
constexpr size_t kNodeDir1Block = kAddrsPerInode + 1;
constexpr size_t kNodeDir2Block = kAddrsPerInode + 2;
constexpr size_t kNodeInd1Block = kAddrsPerInode + 3;
constexpr size_t kNodeInd2Block = kAddrsPerInode + 4;
constexpr size_t kNodeDIndBlock = kAddrsPerInode + 5;

// For superblock

// CountType for monitoring
//
// f2fs monitors the number of several block types such as on-writeback,
// dirty dentry blocks, dirty node blocks, and dirty meta blocks.
enum class CountType {
  kWriteback = 0,
  kDirtyDents,
  kDirtyNodes,
  kDirtyMeta,
  kNrCountType,
};

// The locking order between these classes is
// LockType::FileOp -> LockType::kNodeOp
enum class LockType {
  kFileOp,  // for file op
  kNodeOp,  // for node op
  kNrLockType,
};

// The below are the page types.
// The available types are:
// kData         User data pages. It operates as async mode.
// kNode         Node pages. It operates as async mode.
// kMeta         FS metadata pages such as SIT, NAT, CP.
// kNrPageType   The number of page types.
// kMetaFlush    Make sure the previous pages are written
//               with waiting the bio's completion
// ...           Only can be used with META.
enum class PageType {
  kData = 0,
  kNode,
  kMeta,
  kNrPageType,
  kMetaFlush,
};

struct SbInfo {
  // super_block *sb;			// pointer to VFS super block
  // buffer_head *raw_super_buf;	// buffer head of raw sb
  const SuperBlock *raw_super;  // raw super block pointer
  int s_dirty = 0;              // dirty flag for checkpoint

  // for node-related operations
  NmInfo *nm_info = nullptr;  // node manager
  // inode *node_inode;		// cache node blocks
  fbl::RefPtr<VnodeF2fs> node_vnode;

  // for segment-related operations
  SmInfo *sm_info = nullptr;                                            // segment manager
  struct bio *bio[static_cast<int>(PageType::kNrPageType)];             // bios to merge
  sector_t last_block_in_bio[static_cast<int>(PageType::kNrPageType)];  // last block number
  // rw_semaphore bio_sem;		// IO semaphore

  // for checkpoint
  Checkpoint *ckpt = nullptr;  // raw checkpoint pointer
  // inode *meta_inode;		// cache meta blocks
  fbl::RefPtr<VnodeF2fs> meta_vnode;
  fbl::Mutex cp_mutex;                                               // for checkpoint procedure
  fs::SharedMutex fs_lock[static_cast<int>(LockType::kNrLockType)];  // for blocking FS operations
  fbl::Mutex writepages;                                             // mutex for writepages()
  int por_doing = 0;                                                 // recovery is doing or not

  // for orphan inode management
  list_node_t orphan_inode_list;       // orphan inode list
  fs::SharedMutex orphan_inode_mutex;  // for orphan inode list
  uint64_t n_orphans = 0;              // # of orphan inodes

  // for directory inode management
  list_node_t dir_inode_list;  // dir inode list
  fbl::Mutex dir_inode_lock;   // for dir inode list lock
  uint64_t n_dirty_dirs = 0;   // # of dir inodes

  // basic file system units
  uint64_t log_sectors_per_block = 0;    // log2 sectors per block
  uint64_t log_blocksize = 0;            // log2 block size
  uint64_t blocksize = 0;                // block size
  uint64_t root_ino_num = 0;             // root inode numbe
  uint64_t node_ino_num = 0;             // node inode numbe
  uint64_t meta_ino_num = 0;             // meta inode numbe
  uint64_t log_blocks_per_seg = 0;       // log2 blocks per segment
  uint64_t blocks_per_seg = 0;           // blocks per segment
  uint64_t segs_per_sec = 0;             // segments per section
  uint64_t secs_per_zone = 0;            // sections per zone
  uint64_t total_sections = 0;           // total section count
  uint64_t total_node_count = 0;         // total node block count
  uint64_t total_valid_node_count = 0;   // valid node block count
  uint64_t total_valid_inode_count = 0;  // valid inode count
  int active_logs = 0;                   // # of active logs

  block_t user_block_count = 0;                                  // # of user blocks
  block_t total_valid_block_count = 0;                           // # of valid blocks
  block_t alloc_valid_block_count = 0;                           // # of allocated blocks
  block_t last_valid_block_count = 0;                            // for recovery
  uint32_t s_next_generation = 0;                                // for NFS support
  atomic_t nr_pages[static_cast<int>(CountType::kNrCountType)];  // # of pages, see count_type

  uint64_t mount_opt = 0;  // set with kMountOptxxxx bits according to F2fs::mount_options_

  // for cleaning operations
  fs::SharedMutex gc_mutex;                    // mutex for GC
  struct F2fsGc_kthread *gc_thread = nullptr;  // GC thread

  // for stat information.
  // one is for the LFS mode, and the other is for the SSR mode.
  struct f2fs_stat_info *stat_info = nullptr;  // FS status information
  uint64_t segment_count[2];                   // # of allocated segments
  uint64_t block_count[2];                     // # of allocated blocks
  uint64_t last_victim[2];                     // last victim segment #
  int total_hit_ext = 0, read_hit_ext = 0;     // extent cache hit ratio
  int bg_gc = 0;                               // background gc calls
  fbl::Mutex stat_lock;                        // lock for stat operations
};

static inline const SuperBlock *RawSuper(SbInfo *sbi) {
  return static_cast<const SuperBlock *>(sbi->raw_super);
}

static inline Checkpoint *GetCheckpoint(SbInfo *sbi) {
  return static_cast<Checkpoint *>(sbi->ckpt);
}

static inline NmInfo *GetNmInfo(SbInfo *sbi) { return static_cast<NmInfo *>(sbi->nm_info); }

static inline SmInfo *GetSmInfo(SbInfo *sbi) { return static_cast<SmInfo *>(sbi->sm_info); }

static inline SitInfo *GetSitInfo(SbInfo *sbi) {
  return static_cast<SitInfo *>((GetSmInfo(sbi)->SitInfo));
}

static inline FreeSegmapInfo *GetFreeInfo(SbInfo *sbi) {
  return static_cast<FreeSegmapInfo *>(GetSmInfo(sbi)->free_info);
}

static inline DirtySeglistInfo *GetDirtyInfo(SbInfo *sbi) {
  return static_cast<DirtySeglistInfo *>(GetSmInfo(sbi)->dirty_info);
}

static inline void SetSbDirt(SbInfo *sbi) { sbi->s_dirty = 1; }

static inline void ResetSbDirt(SbInfo *sbi) { sbi->s_dirty = 0; }

static inline void mutex_lock_op(SbInfo *sbi, LockType t)
    TA_ACQ(&sbi->fs_lock[static_cast<int>(t)]) {
  sbi->fs_lock[static_cast<int>(t)].lock();
}

static inline void mutex_unlock_op(SbInfo *sbi, LockType t)
    TA_REL(&sbi->fs_lock[static_cast<int>(t)]) {
  sbi->fs_lock[static_cast<int>(t)].unlock();
}

constexpr uint32_t kDefaultAllocatedBlocks = 1;

[[maybe_unused]] static inline void IncPageCount(SbInfo *sbi, int count_type) {
  // TODO: IMPL
  // AtomicInc(&sbi->nr_pages[count_type]);
  SetSbDirt(sbi);
}

static inline void InodeIncDirtyDents(VnodeF2fs *vnode) {
  //   //TODO: IMPL
  // 	//AtomicInc(&F2FS_I(inode)->dirty_dents);
}

static inline void DecPageCount(SbInfo *sbi, CountType count_type) {
  // TODO: IMPL
  // AtomicDec(&sbi->nr_pages[count_type]);
}

static inline void InodeDecDirtyDents(void *vnode) {
  //   //TODO: IMPL
  // 	//AtomicDec(&F2FS_I(inode)->dirty_dents);
}

static inline int GetPages(SbInfo *sbi, CountType count_type) {
  // TODO: IMPL
  // return AtomicRead(&sbi->nr_pages[count_type]);
  return 0;
}

static inline uint32_t BitmapSize(SbInfo *sbi, MetaBitmap flag) {
  Checkpoint *ckpt = GetCheckpoint(sbi);

  // return NAT or SIT bitmap
  if (flag == MetaBitmap::kNatBitmap)
    return LeToCpu(ckpt->nat_ver_bitmap_bytesize);
  else if (flag == MetaBitmap::kSitBitmap)
    return LeToCpu(ckpt->sit_ver_bitmap_bytesize);

  return 0;
}

static inline void *BitmapPrt(SbInfo *sbi, MetaBitmap flag) {
  Checkpoint *ckpt = GetCheckpoint(sbi);
  int offset = (flag == MetaBitmap::kNatBitmap) ? ckpt->sit_ver_bitmap_bytesize : 0;
  return &ckpt->sit_nat_version_bitmap + offset;
}

static inline bool IsSetCkptFlags(Checkpoint *cp, uint32_t f) {
  uint32_t ckpt_flags = LeToCpu(cp->ckpt_flags);
  return ckpt_flags & f;
}

static inline block_t StartCpAddr(SbInfo *sbi) {
  block_t start_addr;
  Checkpoint *ckpt = GetCheckpoint(sbi);
  uint64_t ckpt_version = LeToCpu(ckpt->checkpoint_ver);

  start_addr = LeToCpu(RawSuper(sbi)->cp_blkaddr);

  // odd numbered checkpoint should at cp segment 0
  // and even segent must be at cp segment 1
  if (!(ckpt_version & 1))
    start_addr += sbi->blocks_per_seg;

  return start_addr;
}

[[maybe_unused]] static inline block_t StartSumAddr(SbInfo *sbi) {
  return LeToCpu(GetCheckpoint(sbi)->cp_pack_start_sum);
}

inline void F2fsPutPage(Page *page, int unlock) {
  if (page != nullptr)
    delete page;
}

static inline void F2fsPutDnode(DnodeOfData *dn) {
  // TODO: IMPL
  if (dn->node_page)
    F2fsPutPage(dn->node_page, 1);
  if (dn->inode_page && dn->node_page != dn->inode_page)
    F2fsPutPage(dn->inode_page, 0);
  dn->node_page = NULL;
  dn->inode_page = NULL;
}

[[maybe_unused]] static inline struct kmem_cache *KmemCacheCreate(const char *name, size_t size,
                                                                  void (*ctor)(void *)) {
  return nullptr;
}

inline bool RawIsInode(Node *p) { return p->footer.nid == p->footer.ino; }

static inline bool IsInode(Page *page) {
  Node *p = static_cast<Node *>(PageAddress(page));
  return RawIsInode(p);
}

static inline uint32_t *BlkaddrInNode(Node *node) {
  return RawIsInode(node) ? node->i.i_addr : node->dn.addr;
}

static inline block_t DatablockAddr(Page *node_page, uint64_t offset) {
  Node *raw_node;
  uint32_t *addr_array;
  raw_node = static_cast<Node *>(PageAddress(node_page));
  addr_array = BlkaddrInNode(raw_node);
  return LeToCpu(addr_array[offset]);
}

static inline int TestValidBitmap(uint64_t nr, char *addr) {
  int mask;

  addr += (nr >> 3);
  mask = 1 << (7 - (nr & 0x07));
  return mask & *addr;
}

static inline int SetValidBitmap(uint64_t nr, char *addr) {
  int mask;
  int ret;

  addr += (nr >> 3);
  mask = 1 << (7 - (nr & 0x07));
  ret = mask & *addr;
  *addr |= mask;
  return ret;
}

static inline int ClearValidBitmap(uint64_t nr, char *addr) {
  int mask;
  int ret;

  addr += (nr >> 3);
  mask = 1 << (7 - (nr & 0x07));
  ret = mask & *addr;
  *addr &= ~mask;
  return ret;
}

// InodeInfo->flags keeping only in memory
enum class InodeInfoFlag {
  kInit = 0,      // indicate inode is being initialized
  kActive,        // indicate open_count > 0
  kDirty,         // indicate dirty vnode
  kNewInode,      // indicate newly allocated vnode
  kNeedCp,        // need to do checkpoint during fsync
  kIncLink,       // need to increment i_nlink
  kAclMode,       // indicate acl mode
  kNoAlloc,       // should not allocate any blocks
  kUpdateDir,     // should update inode block for consistency
  kInlineXattr,   // used for inline xattr
  kInlineData,    // used for inline data
  kInlineDentry,  // used for inline dentry
  kBad,           // should drop this inode without purging
};

#if 0  // porting needed
[[maybe_unused]] static inline void SetAclInode(InodeInfo *fi, umode_t mode) {
  fi->i_acl_mode = mode;
  SetInodeFlag(fi, InodeInfoFlag::kAclMode);
}

[[maybe_unused]] static inline int CondClearInodeFlag(InodeInfo *fi, InodeInfoFlag flag) {
  if (IsInodeFlagSet(fi, InodeInfoFlag::kAclMode)) {
    ClearInodeFlag(fi, InodeInfoFlag::kAclMode);
    return 1;
  }
  return 0;
}
#endif

inline uint32_t RootIno(SbInfo *sbi) { return sbi->root_ino_num; }
inline uint32_t NodeIno(SbInfo *sbi) { return sbi->node_ino_num; }
inline uint32_t MetaIno(SbInfo *sbi) { return sbi->meta_ino_num; }

}  // namespace f2fs

#endif  // THIRD_PARTY_F2FS_F2FS_INTERNAL_H_
