// 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,
};

#define S_SHIFT 12
static unsigned char type_by_mode[S_IFMT >> S_SHIFT] = {
    [S_IFREG >> S_SHIFT] = F2FS_FT_REG_FILE, [S_IFDIR >> S_SHIFT] = F2FS_FT_DIR,
    [S_IFCHR >> S_SHIFT] = F2FS_FT_CHRDEV,   [S_IFBLK >> S_SHIFT] = F2FS_FT_BLKDEV,
    [S_IFIFO >> S_SHIFT] = F2FS_FT_FIFO,     [S_IFSOCK >> S_SHIFT] = F2FS_FT_SOCK,
    [S_IFLNK >> S_SHIFT] = 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 *F2fsFindEntry(fbl::StringPiece name, Page **res_page);
  f2fs_dir_entry *F2fsParentDir(Page **p);
  ino_t F2fsInodeByName(fbl::StringPiece name);
  void F2fsSetLink(f2fs_dir_entry *de, Page *page, VnodeF2fs *inode);
  void InitDentInode(VnodeF2fs *vnode, Page *ipage);
  zx_status_t InitInodeMetadata(VnodeF2fs *vnode, dentry *dentry);
  void UpdateParentMetadata(VnodeF2fs *inode, unsigned int current_depth);
  int RoomForFilename(f2fs_dentry_block *dentry_blk, int slots);
  zx_status_t F2fsAddLink(fbl::StringPiece name, VnodeF2fs *vnode);
  void F2fsDeleteEntry(f2fs_dir_entry *dentry, Page *page, VnodeF2fs *vnode);
  zx_status_t F2fsMakeEmpty(VnodeF2fs *vnode, VnodeF2fs *parent);
  bool F2fsEmptyDir();

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

}  // namespace f2fs

#endif  // F2FS_DIR_H_
