// 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 F2FS_DIR_H_
#define F2FS_DIR_H_

#include <dirent.h>
#include <sys/stat.h>

namespace f2fs {

static unsigned char filetype_table[F2FS_FT_MAX] = {
    [F2FS_FT_UNKNOWN] = DT_UNKNOWN, [F2FS_FT_REG_FILE] = DT_REG, [F2FS_FT_DIR] = DT_DIR,
    [F2FS_FT_CHRDEV] = DT_CHR,      [F2FS_FT_BLKDEV] = DT_BLK,   [F2FS_FT_FIFO] = DT_FIFO,
    [F2FS_FT_SOCK] = DT_SOCK,       [F2FS_FT_SYMLINK] = DT_LNK,
};

constexpr unsigned int kStatShift = 12;

static unsigned char type_by_mode[S_IFMT >> kStatShift] = {
    [S_IFREG >> kStatShift] = F2FS_FT_REG_FILE, [S_IFDIR >> kStatShift] = F2FS_FT_DIR,
    [S_IFCHR >> kStatShift] = F2FS_FT_CHRDEV,   [S_IFBLK >> kStatShift] = F2FS_FT_BLKDEV,
    [S_IFIFO >> kStatShift] = F2FS_FT_FIFO,     [S_IFSOCK >> kStatShift] = F2FS_FT_SOCK,
    [S_IFLNK >> kStatShift] = F2FS_FT_SYMLINK,
};

class Dir : public VnodeF2fs {
 public:
  explicit Dir(F2fs *fs);
  explicit Dir(F2fs *fs, ino_t ino);
  ~Dir() = default;

  zx_status_t Lookup(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> *out) final;
  zx_status_t Readdir(fs::VdirCookie *cookie, void *dirents, size_t len, size_t *out_actual) final;
  zx_status_t Create(fbl::StringPiece name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out) final;
  zx_status_t Link(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> _target) final;
  zx_status_t Unlink(fbl::StringPiece name, bool must_be_dir) final;
  zx_status_t Rename(fbl::RefPtr<fs::Vnode> _newdir, fbl::StringPiece oldname,
                     fbl::StringPiece newname, bool src_must_be_dir, bool dst_must_be_dir);

  uint64_t DirBlocks();
  static unsigned int DirBuckets(unsigned int level);
  static unsigned int BucketBlocks(unsigned int level);
  void SetDeType(f2fs_dir_entry *de, VnodeF2fs *vnode);
  static uint64_t DirBlockIndex(unsigned int level, unsigned int idx);
  bool EarlyMatchName(const char *name, int namelen, f2fs_hash_t namehash,
                      f2fs_dir_entry *de);
  f2fs_dir_entry *FindInBlock(Page *dentry_page, const char *name, int namelen,
                                     int *max_slots, f2fs_hash_t namehash, Page **res_page);
  f2fs_dir_entry *FindInLevel(unsigned int level, fbl::StringPiece name, int namelen,
                                     f2fs_hash_t namehash, Page **res_page);
  f2fs_dir_entry *FindEntry(fbl::StringPiece name, Page **res_page);
  f2fs_dir_entry *ParentDir(Page **p);
  ino_t InodeByName(fbl::StringPiece name);
  void SetLink(f2fs_dir_entry *de, Page *page, VnodeF2fs *inode);
  void InitDentInode(VnodeF2fs *vnode, Page *ipage);
#if 0  // porting needed
  // zx_status_t InitInodeMetadata(VnodeF2fs *vnode, dentry *dentry);
#else
  zx_status_t InitInodeMetadata(VnodeF2fs *vnode);
#endif
  void UpdateParentMetadata(VnodeF2fs *inode, unsigned int current_depth);
  int RoomForFilename(f2fs_dentry_block *dentry_blk, int slots);
  zx_status_t AddLink(fbl::StringPiece name, VnodeF2fs *vnode);
  void DeleteEntry(f2fs_dir_entry *dentry, Page *page, VnodeF2fs *vnode);
  zx_status_t MakeEmpty(VnodeF2fs *vnode, VnodeF2fs *parent);
  bool IsEmptyDir();

  zx_status_t NewInode(uint32_t mode, fbl::RefPtr<VnodeF2fs> *out);
  int IsMultimediaFile(const char *s, const char *sub);
  void SetColdFile(const char *name);
  zx_status_t DoCreate(fbl::StringPiece name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out);
#if 0  // porting needed
//   int F2fsLink(dentry *old_dentry, dentry *dentry);
//   dentry *F2fsGetParent(dentry *child);
#endif
  zx_status_t DoUnlink(VnodeF2fs *vnode, fbl::StringPiece name);
#if 0  // porting needed
//   int F2fsSymlink(dentry *dentry, const char *symname);
#endif
  zx_status_t Mkdir(fbl::StringPiece name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out);
  zx_status_t Rmdir(Dir *vnode, fbl::StringPiece name);
#if 0  // porting needed
//   int F2fsMknod(dentry *dentry, umode_t mode, dev_t rdev);
#endif
  zx_status_t DoLookup(fbl::StringPiece name, fbl::RefPtr<fs::Vnode> *out);
};

}  // namespace f2fs

#endif  // F2FS_DIR_H_
