// 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_DIR_H_
#define THIRD_PARTY_F2FS_DIR_H_

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

namespace f2fs {

const unsigned char kFiletypeTable[static_cast<uint8_t>(FileType::kFtMax)] = {
    [static_cast<uint8_t>(FileType::kFtUnknown)] = DT_UNKNOWN,
    [static_cast<uint8_t>(FileType::kFtRegFile)] = DT_REG,
    [static_cast<uint8_t>(FileType::kFtDir)] = DT_DIR,
    [static_cast<uint8_t>(FileType::kFtChrdev)] = DT_CHR,
    [static_cast<uint8_t>(FileType::kFtBlkdev)] = DT_BLK,
    [static_cast<uint8_t>(FileType::kFtFifo)] = DT_FIFO,
    [static_cast<uint8_t>(FileType::kFtSock)] = DT_SOCK,
    [static_cast<uint8_t>(FileType::kFtSymlink)] = DT_LNK,
};

constexpr unsigned int kStatShift = 12;

const unsigned char kTypeByMode[S_IFMT >> kStatShift] = {
    [S_IFREG >> kStatShift] = static_cast<uint8_t>(FileType::kFtRegFile),
    [S_IFDIR >> kStatShift] = static_cast<uint8_t>(FileType::kFtDir),
    [S_IFCHR >> kStatShift] = static_cast<uint8_t>(FileType::kFtChrdev),
    [S_IFBLK >> kStatShift] = static_cast<uint8_t>(FileType::kFtBlkdev),
    [S_IFIFO >> kStatShift] = static_cast<uint8_t>(FileType::kFtFifo),
    [S_IFSOCK >> kStatShift] = static_cast<uint8_t>(FileType::kFtSock),
    [S_IFLNK >> kStatShift] = static_cast<uint8_t>(FileType::kFtSymlink),
};

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

  zx_status_t Lookup(std::string_view 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(std::string_view name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out) final;
  zx_status_t Link(std::string_view name, fbl::RefPtr<fs::Vnode> _target) final;
  zx_status_t Unlink(std::string_view name, bool must_be_dir) final;
  zx_status_t Rename(fbl::RefPtr<fs::Vnode> _newdir, std::string_view oldname,
                     std::string_view 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(DirEntry *de, VnodeF2fs *vnode);
  static uint64_t DirBlockIndex(unsigned int level, unsigned int idx);
  bool EarlyMatchName(const char *name, int namelen, f2fs_hash_t namehash, DirEntry *de);
  DirEntry *FindInBlock(Page *dentry_page, const char *name, int namelen, int *max_slots,
                        f2fs_hash_t namehash, Page **res_page);
  DirEntry *FindInLevel(unsigned int level, std::string_view name, int namelen,
                        f2fs_hash_t namehash, Page **res_page);
  DirEntry *FindEntry(std::string_view name, Page **res_page);
  DirEntry *ParentDir(Page **p);
  ino_t InodeByName(std::string_view name);
  void SetLink(DirEntry *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(DentryBlock *dentry_blk, int slots);
  zx_status_t AddLink(std::string_view name, VnodeF2fs *vnode);
  void DeleteEntry(DirEntry *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(std::string_view 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, std::string_view name);
#if 0  // porting needed
//   int F2fsSymlink(dentry *dentry, const char *symname);
#endif
  zx_status_t Mkdir(std::string_view name, uint32_t mode, fbl::RefPtr<fs::Vnode> *out);
  zx_status_t Rmdir(Dir *vnode, std::string_view name);
#if 0  // porting needed
//   int F2fsMknod(dentry *dentry, umode_t mode, dev_t rdev);
#endif
  zx_status_t DoLookup(std::string_view name, fbl::RefPtr<fs::Vnode> *out);
  // Check if possible_child is its subdir
  zx::status<bool> IsSubdir(Dir *possible_dir);
};

}  // namespace f2fs

#endif  // THIRD_PARTY_F2FS_DIR_H_
