// 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.

#include "f2fs.h"

namespace f2fs {

Dir::Dir(F2fs *fs) : VnodeF2fs(fs) {}

Dir::Dir(F2fs *fs, ino_t ino) : VnodeF2fs(fs, ino) {}

uint64_t Dir::DirBlocks() {
  // return ((uint64_t) (i_size_read(inode) + kPageCacheSize - 1))
  //             >> kPageCacheShift;
  // return 0;
  // return Inode().i_blocks - 1;
  return (i_size + kF2fsBlockSize - 1) / kF2fsBlockSize;
}

unsigned int Dir::DirBuckets(unsigned int level) {
  if (level < MAX_DIR_HASH_DEPTH / 2)
    return 1 << level;
  else
    return 1 << ((MAX_DIR_HASH_DEPTH / 2) - 1);
}

unsigned int Dir::BucketBlocks(unsigned int level) {
  if (level < MAX_DIR_HASH_DEPTH / 2)
    return 2;
  else
    return 4;
}

void Dir::SetDeType(f2fs_dir_entry *de, VnodeF2fs *vnode) {
  de->file_type = type_by_mode[(vnode->i_mode & S_IFMT) >> S_SHIFT];
}

uint64_t Dir::DirBlockIndex(unsigned int level, unsigned int idx) {
  uint64_t i;
  uint64_t bidx = 0;

  for (i = 0; i < level; i++)
    bidx += DirBuckets(i) * BucketBlocks(i);
  bidx += idx * BucketBlocks(level);
  return bidx;
}

bool Dir::EarlyMatchName(const char *name, int namelen, f2fs_hash_t namehash,
                         f2fs_dir_entry *de) {
  if (LeToCpu(de->name_len) != namelen)
    return false;

  if (LeToCpu(de->hash_code) != namehash)
    return false;

  return true;
}

f2fs_dir_entry *Dir::FindInBlock(Page *dentry_page, const char *name, int namelen,
                                        int *max_slots, f2fs_hash_t namehash, Page **res_page) {
  f2fs_dir_entry *de;
  uint64_t bit_pos, end_pos, next_pos;
#if 0  // porting needed
  // f2fs_dentry_block *dentry_blk = kmap(dentry_page);
#else
  f2fs_dentry_block *dentry_blk = reinterpret_cast<f2fs_dentry_block *>(dentry_page);
#endif
  int slots;

  bit_pos =
      find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, 0);
  while (bit_pos < NR_DENTRY_IN_BLOCK) {
    de = &dentry_blk->dentry[bit_pos];
    slots = (LeToCpu(de->name_len) + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;

    if (EarlyMatchName(name, namelen, namehash, de)) {
      if (!memcmp(dentry_blk->filename[bit_pos], name, namelen)) {
        *res_page = dentry_page;
        return de;
      }
    }
    next_pos = bit_pos + slots;
    bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK,
                               next_pos);
    if (bit_pos >= NR_DENTRY_IN_BLOCK)
      end_pos = NR_DENTRY_IN_BLOCK;
    else
      end_pos = bit_pos;
    if (static_cast<uint64_t>(*max_slots) < end_pos - next_pos)
      *max_slots = end_pos - next_pos;
  }

  de = nullptr;
#if 0  // porting needed
//   kunmap(dentry_page);
#endif
  return de;
}

f2fs_dir_entry *Dir::FindInLevel(unsigned int level, fbl::StringPiece name, int namelen,
                                        f2fs_hash_t namehash, Page **res_page) {
  int s = (namelen + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
  unsigned int nbucket, nblock;
  unsigned int bidx, end_block;
  Page *dentry_page = nullptr;
  f2fs_dir_entry *de = nullptr;
  bool room = false;
  int max_slots = 0;

  ZX_ASSERT(level <= MAX_DIR_HASH_DEPTH);

  nbucket = DirBuckets(level);
  nblock = BucketBlocks(level);

  bidx = DirBlockIndex(level, namehash % nbucket);
  end_block = bidx + nblock;

  for (; bidx < end_block; bidx++) {
    /* no need to allocate new dentry pages to all the indices */
    if (FindDataPage(bidx, &dentry_page) != ZX_OK) {
      room = true;
      continue;
    }

    if (de = FindInBlock(dentry_page, name.data(), namelen, &max_slots, namehash, res_page); de != nullptr)
      break;

    if (max_slots >= s)
      room = true;
    F2fsPutPage(dentry_page, 0);
  }

  if (!de && room && fi.chash != namehash) {
    fi.chash = namehash;
    fi.clevel = level;
  }

  return de;
}

/*
 * Find an entry in the specified directory with the wanted name.
 * It returns the page where the entry was found (as a parameter - res_page),
 * and the entry itself. Page is returned mapped and unlocked.
 * Entry is guaranteed to be valid.
 */
f2fs_dir_entry *Dir::F2fsFindEntry(fbl::StringPiece name, Page **res_page) {
  uint64_t npages = DirBlocks();
  f2fs_dir_entry *de = nullptr;
  f2fs_hash_t name_hash;
  unsigned int max_depth;
  unsigned int level;

  if (npages == 0)
    return nullptr;

  *res_page = nullptr;

  name_hash = F2fsDentryHash(name.data(), name.length());
  max_depth = fi.i_current_depth;

  for (level = 0; level < max_depth; level++) {
    if (de = FindInLevel(level, name, name.length(), name_hash, res_page); de != nullptr)
      break;
  }
  if (!de && fi.chash != name_hash) {
    fi.chash = name_hash;
    fi.clevel = level - 1;
  }
  return de;
}

f2fs_dir_entry *Dir::F2fsParentDir(Page **p) {
  Page *page = nullptr;
  f2fs_dir_entry *de = nullptr;
  f2fs_dentry_block *dentry_blk = nullptr;

  if (GetLockDataPage(0, &page) != ZX_OK)
    return nullptr;

#if 0  // porting needed
  // dentry_blk = kmap(page);
#endif
  dentry_blk = static_cast<f2fs_dentry_block *>(PageAddress(page));
  de = &dentry_blk->dentry[1];
  *p = page;
#if 0  // porting needed
  // unlock_page(page);
#endif
  return de;
}

ino_t Dir::F2fsInodeByName(fbl::StringPiece name) {
  ino_t res = 0;
  f2fs_dir_entry *de;
  Page *page;

  if (de = F2fsFindEntry(name, &page); de != nullptr) {
    res = LeToCpu(de->ino);
#if 0  // porting needed
    // kunmap(page);
#endif
    F2fsPutPage(page, 0);
  }

  return res;
}

void Dir::F2fsSetLink(f2fs_dir_entry *de, Page *page, VnodeF2fs *vnode) {
  f2fs_sb_info &sbi = Vfs()->SbInfo();

  fbl::AutoLock lock(&sbi.fs_lock[DENTRY_OPS]);
#if 0  // porting needed
  // lock_page(page);
#endif
  WaitOnPageWriteback(page);
  de->ino = CpuToLe(vnode->Ino());
  SetDeType(de, vnode);
#if 0  // porting needed
  // kunmap(page);
  // set_page_dirty(page);
#else
  FlushDirtyDataPage(Vfs(), page);
#endif

  auto cur_time = time(nullptr);
  i_mtime.tv_sec = cur_time;
  i_mtime.tv_nsec = 0;
  i_ctime.tv_sec = cur_time;
  i_ctime.tv_nsec = 0;
  MarkInodeDirty(this);
  F2fsPutPage(page, 1);
}

void Dir::InitDentInode(VnodeF2fs *vnode, Page *ipage) {
#if 0  // porting needed
  // inode *dir = dentry->d_parent->d_inode;
#endif
  f2fs_node *rn;

  if (!ipage)
    return;

  WaitOnPageWriteback(ipage);

  /* copy dentry info. to this inode page */
  rn = static_cast<f2fs_node *>(PageAddress(ipage));
  rn->i.i_pino = CpuToLe(Ino());
  rn->i.i_namelen = CpuToLe(vnode->i_name_sp.length());
  memcpy(rn->i.i_name, vnode->i_name_sp.data(), vnode->i_name_sp.length());
#if 0  // porting needed
  // set_page_dirty(ipage);
#else
  FlushDirtyNodePage(Vfs(), ipage);
#endif
}

zx_status_t Dir::InitInodeMetadata(VnodeF2fs *vnode, dentry *dentry) {
#if 0  // porting needed
  // inode *dir = dentry->d_parent->d_inode;
#endif

  if (is_inode_flag_set(&vnode->fi, FI_NEW_INODE)) {
    if (zx_status_t err = Vfs()->Nodemgr().NewInodePage(this, vnode); err != ZX_OK)
      return err;

    if (S_ISDIR(vnode->i_mode)) {
      if (zx_status_t err = F2fsMakeEmpty(vnode, this); err != ZX_OK) {
        Vfs()->Nodemgr().RemoveInodePage(vnode);
        return err;
      }
    }

#if 0  // porting needed
    // err = f2fs_init_acl(inode, dir);
    // if (err) {
    //   remove_inode_page(inode);
    //   return err;
    // }
#endif
  } else {
    Page *ipage = nullptr;

    if (zx_status_t err = Vfs()->Nodemgr().GetNodePage(vnode->Ino(), &ipage); err != ZX_OK)
      return err;
    InitDentInode(vnode, ipage);
    F2fsPutPage(ipage, 1);
  }
  if (is_inode_flag_set(&vnode->fi, FI_INC_LINK)) {
    vnode->IncNlink();
    vnode->F2fsWriteInode(NULL);
  }
  return 0;
}

void Dir::UpdateParentMetadata(VnodeF2fs *vnode, unsigned int current_depth) {
  bool need_dir_update = false;

  if (is_inode_flag_set(&vnode->fi, FI_NEW_INODE)) {
    if (S_ISDIR(vnode->i_mode)) {
      IncNlink();
      need_dir_update = true;
    }
    ClearInodeFlag(&vnode->fi, FI_NEW_INODE);
  }

  auto cur_time = time(nullptr);
  i_mtime.tv_sec = cur_time;
  i_mtime.tv_nsec = 0;
  i_ctime.tv_sec = cur_time;
  i_ctime.tv_nsec = 0;
  if (fi.i_current_depth != current_depth) {
    fi.i_current_depth = current_depth;
    need_dir_update = true;
  }

  if (need_dir_update)
    F2fsWriteInode(NULL);
  else
    MarkInodeDirty(this);

  if (is_inode_flag_set(&vnode->fi, FI_INC_LINK))
    ClearInodeFlag(&vnode->fi, FI_INC_LINK);
}

int Dir::RoomForFilename(f2fs_dentry_block *dentry_blk, int slots) {
  int bit_start = 0;
  int zero_start, zero_end;

  while (true) {
    zero_start = find_next_zero_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, bit_start);
    if (zero_start >= NR_DENTRY_IN_BLOCK)
      return NR_DENTRY_IN_BLOCK;

    zero_end = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, zero_start);
    if (zero_end - zero_start >= slots)
      return zero_start;

    bit_start = zero_end + 1;

    if (zero_end + 1 >= NR_DENTRY_IN_BLOCK)
      return NR_DENTRY_IN_BLOCK;
  }
}

zx_status_t Dir::F2fsAddLink(fbl::StringPiece name, VnodeF2fs *vnode) {
  unsigned int bit_pos;
  unsigned int level;
  unsigned int current_depth;
  uint64_t bidx, block;
  f2fs_hash_t dentry_hash;
  f2fs_dir_entry *de;
  unsigned int nbucket, nblock;
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  int namelen = name.length();
  Page *dentry_page = nullptr;
  f2fs_dentry_block *dentry_blk = nullptr;
  int slots = (namelen + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
  zx_status_t err = 0;
  int i;

  dentry_hash = F2fsDentryHash(name.data(), namelen);
  level = 0;
  current_depth = fi.i_current_depth;
  if (fi.chash == dentry_hash) {
    level = fi.clevel;
    fi.chash = 0;
  }

  while (true) {
    if (current_depth == MAX_DIR_HASH_DEPTH)
      return ZX_ERR_OUT_OF_RANGE;

    /* Increase the depth, if required */
    if (level == current_depth)
      ++current_depth;

    nbucket = DirBuckets(level);
    nblock = BucketBlocks(level);

    bidx = DirBlockIndex(level, (dentry_hash % nbucket));

    for (block = bidx; block <= (bidx + nblock - 1); block++) {
      fbl::AutoLock lock(&sbi.fs_lock[DENTRY_OPS]);
      if (err = GetNewDataPage(block, true, &dentry_page); err != ZX_OK) {
        return err;
      }

#if 0  // porting needed
      // dentry_blk = kmap(dentry_page);
#else
      dentry_blk = reinterpret_cast<f2fs_dentry_block *>(dentry_page->data);
#endif
      bit_pos = RoomForFilename(dentry_blk, slots);
      if (bit_pos < NR_DENTRY_IN_BLOCK) {
#if 0  // porting needed
        // if (err = InitInodeMetadata(vnode, dentry); err == ZX_OK) {
#else
        if (err = InitInodeMetadata(vnode, nullptr); err == ZX_OK) {
#endif
          WaitOnPageWriteback(dentry_page);

          de = &dentry_blk->dentry[bit_pos];
          de->hash_code = CpuToLe(dentry_hash);
          de->name_len = CpuToLe(static_cast<uint16_t>(namelen));
          memcpy(dentry_blk->filename[bit_pos], name.data(), namelen);
          de->ino = CpuToLe(vnode->Ino());
          SetDeType(de, vnode);
          for (i = 0; i < slots; i++)
            test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);
#if 0  // porting needed
          // set_page_dirty(dentry_page);
#else
          FlushDirtyDataPage(Vfs(), dentry_page);
#endif
          UpdateParentMetadata(vnode, current_depth);
        }

#if 0  // porting needed
        // kunmap(dentry_page);
#endif
        F2fsPutPage(dentry_page, 1);
        return err;
      }

#if 0  // porting needed
      // kunmap(dentry_page);
#endif
      F2fsPutPage(dentry_page, 1);
    }

    /* Move to next level to find the empty slot for new dentry */
    ++level;
  }
}

/**
 * It only removes the dentry from the dentry page,corresponding name
 * entry in name page does not need to be touched during deletion.
 */
void Dir::F2fsDeleteEntry(f2fs_dir_entry *dentry, Page *page, VnodeF2fs *vnode) {
  f2fs_dentry_block *dentry_blk;
  unsigned int bit_pos;
#if 0  // porting needed
  // address_space *mapping = page->mapping;
#endif
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  int slots = (LeToCpu(dentry->name_len) + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
  void *kaddr = PageAddress(page);
  int i;

  fbl::AutoLock lock(&sbi.fs_lock[DENTRY_OPS]);

#if 0  // porting needed
  // lock_page(page);
#endif
  WaitOnPageWriteback(page);

  dentry_blk = static_cast<f2fs_dentry_block *>(kaddr);
  bit_pos = dentry - dentry_blk->dentry;
  for (i = 0; i < slots; i++)
    test_and_clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);

  /* Let's check and deallocate this dentry page */
  bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, 0);
#if 0  // porting needed
  // kunmap(page); /* kunmap - pair of f2fs_find_entry */
  // set_page_dirty(page);
#else
  FlushDirtyDataPage(Vfs(), page);
#endif

  auto cur_time = time(nullptr);
  i_mtime.tv_sec = cur_time;
  i_mtime.tv_nsec = 0;
  i_ctime.tv_sec = cur_time;
  i_ctime.tv_nsec = 0;

  if (vnode && S_ISDIR(vnode->i_mode)) {
    DropNlink();
    F2fsWriteInode(NULL);
  } else {
    MarkInodeDirty(this);
  }

  if (vnode) {
    cur_time = time(nullptr);
    i_ctime.tv_sec = cur_time;
    i_ctime.tv_nsec = 0;
    i_mtime.tv_sec = cur_time;
    i_mtime.tv_nsec = 0;
    vnode->i_ctime.tv_sec = cur_time;
    vnode->i_ctime.tv_nsec = 0;
    vnode->DropNlink();
    if (S_ISDIR(vnode->i_mode)) {
      vnode->DropNlink();
      vnode->i_size = 0;
    }
    vnode->F2fsWriteInode(NULL);
    if (vnode->i_nlink == 0)
      Vfs()->AddOrphanInode(vnode->Ino());
  }

  if (bit_pos == NR_DENTRY_IN_BLOCK) {
    loff_t page_offset;
    TruncateHole(page->index, page->index + 1);
    ClearPageDirtyForIo(page);
#if 0  // porting needed
    // ClearPageUptodate(page);
#endif
    DecPageCount(&sbi, F2FS_DIRTY_DENTS);
    InodeDecDirtyDents(this);
    page_offset = page->index << kPageCacheShift;
    F2fsPutPage(page, 1);
  } else {
    F2fsPutPage(page, 1);
  }
}

zx_status_t Dir::F2fsMakeEmpty(VnodeF2fs *vnode, VnodeF2fs *parent) {
  Page *dentry_page = nullptr;
  f2fs_dentry_block *dentry_blk;
  f2fs_dir_entry *de;
  void *kaddr;

  if (zx_status_t err = vnode->GetNewDataPage(0, true, &dentry_page); err != ZX_OK)
    return err;

#if 0  // porting needed
  // kaddr = kmap_atomic(dentry_page);
#else
  kaddr = dentry_page->data;
#endif
  dentry_blk = static_cast<f2fs_dentry_block *>(kaddr);

  de = &dentry_blk->dentry[0];
  de->name_len = CpuToLe(static_cast<uint16_t>(1));
  de->hash_code = 0;
  de->ino = CpuToLe(vnode->Ino());
  memcpy(dentry_blk->filename[0], ".", 1);
  SetDeType(de, vnode);

  de = &dentry_blk->dentry[1];
  de->hash_code = 0;
  de->name_len = CpuToLe(static_cast<uint16_t>(2));
  de->ino = CpuToLe(parent->Ino());
  memcpy(dentry_blk->filename[1], "..", 2);
  SetDeType(de, vnode);

  test_and_set_bit_le(0, &dentry_blk->dentry_bitmap);
  test_and_set_bit_le(1, &dentry_blk->dentry_bitmap);
#if 0  // porting needed
  // kunmap_atomic(kaddr);
  // set_page_dirty(dentry_page);
#else
  FlushDirtyDataPage(Vfs(), dentry_page);
#endif
  F2fsPutPage(dentry_page, 1);
  return 0;
}

bool Dir::F2fsEmptyDir() {
  uint64_t bidx;
  Page *dentry_page = nullptr;
  unsigned int bit_pos;
  f2fs_dentry_block *dentry_blk;
  uint64_t nblock = DirBlocks();

  for (bidx = 0; bidx < nblock; bidx++) {
    void *kaddr;
    
    if (zx_status_t ret = GetLockDataPage(bidx, &dentry_page); ret != ZX_OK) {
      if (ret == ZX_ERR_NOT_FOUND)
        continue;
      else
        return false;
    }

#if 0  // porting needed
    // kaddr = kmap_atomic(dentry_page);
#else
    kaddr = dentry_page->data;
#endif
    dentry_blk = static_cast<f2fs_dentry_block *>(kaddr);
    if (bidx == 0)
      bit_pos = 2;
    else
      bit_pos = 0;
    bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, NR_DENTRY_IN_BLOCK, bit_pos);
#if 0  // porting needed
    // kunmap_atomic(kaddr);
#endif

    F2fsPutPage(dentry_page, 1);

    if (bit_pos < NR_DENTRY_IN_BLOCK)
      return false;
  }
  return true;
}

zx_status_t Dir::Readdir(fs::VdirCookie *cookie, void *dirents, size_t len, size_t *out_actual) {
  fs::DirentFiller df(dirents, len);
  uint64_t *pos_cookie = reinterpret_cast<uint64_t *>(cookie);
  uint64_t pos = *pos_cookie;
  uint64_t npages = DirBlocks();
  unsigned char *types = nullptr;
  unsigned int bit_pos = 0, start_bit_pos = 0;
  f2fs_dentry_block *dentry_blk = nullptr;
  f2fs_dir_entry *de = nullptr;
  Page *dentry_page = nullptr;
  unsigned int n = 0;
  unsigned char d_type = DT_UNKNOWN;
  int slots;
  zx_status_t ret = ZX_OK;
  bool done = false;

  fbl::AutoLock lock(&i_mutex);

  types = filetype_table;
  bit_pos = (pos % NR_DENTRY_IN_BLOCK);
  n = (pos / NR_DENTRY_IN_BLOCK);

  for (; n < npages; n++) {
    if (ret = GetLockDataPage(n, &dentry_page); ret != ZX_OK)
      continue;

    start_bit_pos = bit_pos;
#if 0  // porting needed
    //     dentry_blk = kmap(dentry_page);
#else
    dentry_blk = reinterpret_cast<f2fs_dentry_block *>(dentry_page);
#endif
    while (bit_pos < NR_DENTRY_IN_BLOCK) {
      d_type = DT_UNKNOWN;
      bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap,
                                 NR_DENTRY_IN_BLOCK, bit_pos);
      if (bit_pos >= NR_DENTRY_IN_BLOCK)
        break;

      de = &dentry_blk->dentry[bit_pos];
      if (types && de->file_type < F2FS_FT_MAX)
        d_type = types[de->file_type];

      fbl::StringPiece name(reinterpret_cast<char *>(dentry_blk->filename[bit_pos]), LeToCpu(de->name_len));

      if ((ret = df.Next(name, d_type, LeToCpu(de->ino))) != ZX_OK) {
        *pos_cookie += bit_pos - start_bit_pos;
        done = true;
        break;
      }

      slots = (LeToCpu(de->name_len) + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
      bit_pos += slots;
    }
    if (done)
      break;

    bit_pos = 0;
    *pos_cookie = (n + 1) * NR_DENTRY_IN_BLOCK;

#if 0  // porting needed
    //     kunmap(dentry_page);
#endif
    F2fsPutPage(dentry_page, 1);
    dentry_page = nullptr;
  }

  if (dentry_page && ret == ZX_OK) {
#if 0  // porting needed
    //     kunmap(dentry_page);
#endif
    F2fsPutPage(dentry_page, 1);
  }

  *out_actual = df.BytesFilled();

  return ret;
}

#if 0  // porting needed
// const file_operations f2fs_dir_operations = {
//   .llseek    = generic_file_llseek,
//   .read    = generic_read_dir,
//   .readdir  = f2fs_readdir,
// };
#endif

}  // namespace f2fs
