// 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 <dirent.h>
#include <sys/stat.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>

#include "f2fs.h"

namespace f2fs {

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

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

bool VnodeF2fs::IsDirectory() { return S_ISDIR(inode_.i_mode); }

fs::VnodeProtocolSet VnodeF2fs::GetProtocols() const {
  if (S_ISDIR(inode_.i_mode)) {
    return fs::VnodeProtocol::kDirectory;
  } else {
    return fs::VnodeProtocol::kFile;
  }
}

zx_status_t VnodeF2fs::GetNodeInfoForProtocol([[maybe_unused]] fs::VnodeProtocol protocol,
                                              [[maybe_unused]] fs::Rights rights,
                                              fs::VnodeRepresentation *info) {
  if (IsDirectory()) {
    *info = fs::VnodeRepresentation::Directory();
  } else {
    *info = fs::VnodeRepresentation::File();
  }
  return ZX_OK;
}

void VnodeF2fs::Allocate(F2fs *fs, ino_t ino, uint32_t mode, fbl::RefPtr<VnodeF2fs> *out) {
  /* Check if ino is within scope */
  CheckNidRange(&fs->SbInfo(), ino);

  if (S_ISDIR(mode)) {
    *out = fbl::AdoptRef(new Dir(fs, ino));
  } else {
    *out = fbl::AdoptRef(new File(fs, ino));
  }

  VnodeF2fs *vnode = out->get();

  mtx_init(&vnode->i_mutex_, mtx_plain);

  memset(&vnode->fi_, 0, sizeof(f2fs_inode_info));

#if 0  // porting needed
  // AtomicSet(&vnode->fi.vfs_inode.i_version, 1);
#endif
  AtomicSet(&vnode->fi_.dirty_dents, 0);
  vnode->fi_.i_current_depth = 1;
  vnode->fi_.i_advise = 0;
  RwlockInit(&vnode->fi_.ext.ext_lock);

  SetInodeFlag(&vnode->fi_, FI_NEW_INODE);
}

// TODO(sukka): fill vfs->members in addtion to size
// TODO(sukka): if dir/file vnode are defined as different class, check if the ino is for dir/file
void VnodeF2fs::Create(F2fs *fs, ino_t ino, fbl::RefPtr<VnodeF2fs> *out) {
  Page *node_page = nullptr;
  f2fs_inode *ri;
  f2fs_node *rn;

  if (ino == F2FS_NODE_INO(&fs->SbInfo()) || ino == F2FS_META_INO(&fs->SbInfo())) {
    *out = fbl::AdoptRef(new VnodeF2fs(fs, ino));
    return;
  }

  /* Check if ino is within scope */
  CheckNidRange(&fs->SbInfo(), ino);

  if (fs->Nodemgr().GetNodePage(ino, &node_page) != ZX_OK) {
    return;
  }

  rn = static_cast<f2fs_node *>(PageAddress(node_page));
  ri = &(rn->i);

  // [sukka] need to check result?
  if (S_ISDIR(ri->i_mode)) {
    *out = fbl::AdoptRef(new Dir(fs, ino));
  } else {
    *out = fbl::AdoptRef(new File(fs, ino));
  }

  memcpy(&(*out)->inode_, ri, sizeof(f2fs_inode));

  VnodeF2fs *vnode = out->get();

  mtx_init(&vnode->i_mutex_, mtx_plain);

  vnode->i_mode_ = LeToCpu(ri->i_mode);
  vnode->i_uid_ = LeToCpu(ri->i_uid);
  vnode->i_gid_ = LeToCpu(ri->i_gid);
  vnode->i_nlink_ = ri->i_links;
  vnode->i_size_ = LeToCpu(ri->i_size);
  vnode->i_blocks_ = LeToCpu(ri->i_blocks);

  vnode->i_atime_.tv_sec = LeToCpu(ri->i_atime);
  vnode->i_ctime_.tv_sec = LeToCpu(ri->i_ctime);
  vnode->i_mtime_.tv_sec = LeToCpu(ri->i_mtime);
  vnode->i_atime_.tv_nsec = LeToCpu(ri->i_atime_nsec);
  vnode->i_ctime_.tv_nsec = LeToCpu(ri->i_ctime_nsec);
  vnode->i_mtime_.tv_nsec = LeToCpu(ri->i_mtime_nsec);
  vnode->i_generation_ = LeToCpu(ri->i_generation);

  vnode->fi_.i_current_depth = LeToCpu(ri->i_current_depth);
  vnode->fi_.i_xattr_nid = LeToCpu(ri->i_xattr_nid);
  vnode->fi_.i_flags = LeToCpu(ri->i_flags);
  vnode->fi_.flags = 0;
#if 0  // porting needed
  // vnode->fi.data_version = LeToCpu(F2FS_CKPT(sbi)->checkpoint_ver) - 1;
#endif
  vnode->fi_.i_advise = ri->i_advise;
  RwlockInit(&vnode->fi_.ext.ext_lock);
  GetExtentInfo(&vnode->fi_.ext, ri->i_ext);

  fbl::StringPiece name(reinterpret_cast<char *>(ri->i_name), ri->i_namelen);
  vnode->i_name_sp_ = name;

  F2fsPutPage(node_page, 1);
}

zx_status_t VnodeF2fs::Open([[maybe_unused]] ValidatedOptions options,
                            fbl::RefPtr<Vnode> *out_redirect) {
  fd_count_++;

  return ZX_OK;
}

zx_status_t VnodeF2fs::Close() {
  fd_count_--;

  return ZX_OK;
}

void VnodeF2fs::fbl_recycle() {
  fs_->EraseVnodeFromTable(this);
  delete this;
}

zx_status_t VnodeF2fs::GetAttributes(fs::VnodeAttributes *a) {
#ifdef F2FS_BU_DEBUG
  FX_LOGS(DEBUG) << "f2fs_getattr() vn=" << this << "(#" << ino_ << ")";
#endif
  *a = fs::VnodeAttributes();

  a->mode = i_mode_;
  a->inode = ino_;
  a->content_size = i_size_;
  a->storage_size = i_blocks_ * kF2fsBlockSize;
  a->link_count = i_nlink_;
  a->creation_time = inode_.i_ctime;
  a->modification_time = inode_.i_mtime;

  return ZX_OK;
}

struct f2fs_iget_args {
  uint64_t ino;
  int on_free;
};

#if 0  // porting needed
// void VnodeF2fs::F2fsSetInodeFlags() {
  // uint64_t &flags = fi.i_flags;

  // inode_.i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE |
  //     S_NOATIME | S_DIRSYNC);

  // if (flags & FS_SYNC_FL)
  //   inode_.i_flags |= S_SYNC;
  // if (flags & FS_APPEND_FL)
  //   inode_.i_flags |= S_APPEND;
  // if (flags & FS_IMMUTABLE_FL)
  //   inode_.i_flags |= S_IMMUTABLE;
  // if (flags & FS_NOATIME_FL)
  //   inode_.i_flags |= S_NOATIME;
  // if (flags & FS_DIRSYNC_FL)
  //   inode_.i_flags |= S_DIRSYNC;
// }

// int VnodeF2fs::F2fsIgetTest(void *data) {
  // f2fs_iget_args *args = (f2fs_iget_args *)data;

  // if (ino_ != args->ino)
  //   return 0;
  // if (i_state & (I_FREEING | I_WILL_FREE)) {
  //   args->on_free = 1;
  //   return 0;
  // }
  // return 1;
// }

// VnodeF2fs *VnodeF2fs::F2fsIgetNowait(uint64_t ino) {
//   fbl::RefPtr<VnodeF2fs> vnode_refptr;
//   VnodeF2fs *vnode = nullptr;
//   f2fs_iget_args args = {.ino = ino, .on_free = 0};
//   vnode = ilookup5(sb, ino, F2fsIgetTest, &args);

//   if (vnode)
//     return vnode;
//   if (!args.on_free) {
//     Vget(Vfs(), ino, &vnode_refptr);
//     vnode = vnode_refptr.get();
//     return vnode;
//   }
//   return static_cast<VnodeF2fs *>(ErrPtr(ZX_ERR_NOT_FOUND));
// }
#endif

zx_status_t VnodeF2fs::Vget(F2fs *fs, uint64_t ino, fbl::RefPtr<VnodeF2fs> *out) {
  fbl::RefPtr<VnodeF2fs> vnode_refptr;
  VnodeF2fs *vnode;

  if (fs->FindVnode(&vnode_refptr, ino) == ZX_OK) {
    *out = std::move(vnode_refptr);
    return ZX_OK;
  }

  Create(fs, ino, &vnode_refptr);

  vnode = vnode_refptr.get();

  if (vnode == nullptr) {
    return ZX_ERR_NO_MEMORY;
  }

  fs->InsertVnode(vnode);

  fbl::AutoLock lock(&vnode->v_lock_);

#if 0  // porting needed
  // if (!(vnode->i_state & I_NEW))
  //  return vnode;
#endif

  if (!(ino == F2FS_NODE_INO(&fs->SbInfo()) || ino == F2FS_META_INO(&fs->SbInfo()))) {
    if (!fs->SbInfo().por_doing && vnode->i_nlink_ == 0) {
#if 0  // porting needed
      // iget_failed(inode);
#endif
      return ZX_ERR_NOT_FOUND;
    }
  }

#if 0  // porting needed
  // if (ino == F2FS_NODE_INO(sbi)) {
  //   // inode->i_mapping->a_ops = &f2fs_node_aops; //invalidatepage, releasepage
  //   // mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
  // } else if (ino == F2FS_META_INO(sbi)) {
  //   // inode->i_mapping->a_ops = &f2fs_meta_aops; //empty
  //   // mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
  // } else if (S_ISREG(inode->i_mode)) {
  //   // inode->i_op = &f2fs_file_inode_operations; //empty
  //   // inode->i_fop = &f2fs_file_operations; //empty
  //   // inode->i_mapping->a_ops = &f2fs_dblock_aops;
  // } else if (S_ISDIR(inode->i_mode)) {
  //   // inode->i_op = &f2fs_dir_inode_operations; //lookup only
  //   // inode->i_fop = &f2fs_dir_operations; //read, readdir
  //   // inode->i_mapping->a_ops = &f2fs_dblock_aops; //readpage, readpages, invalidatepage,
  //   releasepage
  //   // mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER_MOVABLE |
  //   //     __GFP_ZERO);
  // } else if (S_ISLNK(inode->i_mode)) {
  //   // inode->i_op = &f2fs_symlink_inode_operations; //empty
  //   // inode->i_mapping->a_ops = &f2fs_dblock_aops;
  // } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
  //     S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
  //   // inode->i_op = &f2fs_special_inode_operations; //empty
  //   init_special_inode(inode, inode->i_mode, inode->i_rdev);
  // } else {
  //     iget_failed(inode);
  //     return ZX_ERR_IO;
  // }
#endif

  *out = std::move(vnode_refptr);

  return ZX_OK;
}

void VnodeF2fs::UpdateInode(Page *node_page) {
  f2fs_node *rn;
  f2fs_inode *ri;

  WaitOnPageWriteback(node_page);

  rn = static_cast<f2fs_node *>(PageAddress(node_page));
  ri = &(rn->i);

  ri->i_mode = CpuToLe(i_mode_);
  ri->i_advise = fi_.i_advise;
  ri->i_uid = CpuToLe(i_uid_);
  ri->i_gid = CpuToLe(i_gid_);
  ri->i_links = CpuToLe(i_nlink_);
  ri->i_size = CpuToLe(static_cast<uint64_t>(i_size_));
  ri->i_blocks = CpuToLe(static_cast<uint64_t>(i_blocks_));
  set_raw_extent(&fi_.ext, &ri->i_ext);

  ri->i_atime = CpuToLe(static_cast<uint64_t>(i_atime_.tv_sec));
  ri->i_ctime = CpuToLe(static_cast<uint64_t>(i_ctime_.tv_sec));
  ri->i_mtime = CpuToLe(static_cast<uint64_t>(i_mtime_.tv_sec));
  ri->i_atime_nsec = CpuToLe(static_cast<uint32_t>(i_atime_.tv_nsec));
  ri->i_ctime_nsec = CpuToLe(static_cast<uint32_t>(i_ctime_.tv_nsec));
  ri->i_mtime_nsec = CpuToLe(static_cast<uint64_t>(i_mtime_.tv_nsec));
  ri->i_current_depth = CpuToLe(fi_.i_current_depth);
  ri->i_xattr_nid = CpuToLe(fi_.i_xattr_nid);
  ri->i_flags = CpuToLe(fi_.i_flags);
  ri->i_generation = CpuToLe(i_generation_);
#if 0  // porting needed
  // set_page_dirty(node_page);
#else
  FlushDirtyNodePage(Vfs(), node_page);
#endif
}

int VnodeF2fs::WriteInode(WritebackControl *wbc) TA_NO_THREAD_SAFETY_ANALYSIS {
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  Page *node_page = nullptr;
  zx_status_t ret = ZX_OK;

  if (ino_ == F2FS_NODE_INO(&sbi) || ino_ == F2FS_META_INO(&sbi))
    return ret;

  if (ret = Vfs()->Nodemgr().GetNodePage(ino_, &node_page); ret != ZX_OK)
    return ret;

  if (PageDirty(node_page)) {
    UpdateInode(node_page);
    F2fsPutPage(node_page, 1);
  } else {
    F2fsPutPage(node_page, 1);
    fbl::AutoLock lock(&sbi.write_inode);
    if (ret = Vfs()->Nodemgr().GetNodePage(ino_, &node_page); ret != ZX_OK)
      return ret;
    UpdateInode(node_page);
    F2fsPutPage(node_page, 1);
  }

  return ZX_OK;
}

#if 0  // porting needed
// void VnodeF2fs::F2fsTruncate() {
//   if (!(S_ISREG(i_mode_) || S_ISDIR(i_mode_) || S_ISLNK(i_mode_)))
//     return;

//   if (!TruncateBlocks(i_size)) {
//     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);
//   }

//   Vfs()->Segmgr().F2fsBalanceFs();
// }
#endif

int VnodeF2fs::TruncateDataBlocksRange(dnode_of_data *dn, int count) {
  int nr_free = 0, ofs = dn->ofs_in_node;
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  f2fs_node *raw_node;
  uint32_t *addr;

  raw_node = static_cast<f2fs_node *>(PageAddress(dn->node_page));
  addr = blkaddr_in_node(raw_node) + ofs;

  for (; count > 0; count--, addr++, dn->ofs_in_node++) {
    block_t blkaddr = LeToCpu(*addr);
    if (blkaddr == NULL_ADDR)
      continue;

    UpdateExtentCache(NULL_ADDR, dn);
    Vfs()->Segmgr().InvalidateBlocks(blkaddr);
    dec_valid_block_count(&sbi, dn->vnode, 1);
    nr_free++;
  }
  if (nr_free) {
#if 0  // porting needed
    // set_page_dirty(dn->node_page);
#else
    FlushDirtyNodePage(Vfs(), dn->node_page);
#endif
    Vfs()->Nodemgr().SyncInodePage(dn);
  }
  dn->ofs_in_node = ofs;
  return nr_free;
}

void VnodeF2fs::TruncateDataBlocks(dnode_of_data *dn) {
  TruncateDataBlocksRange(dn, ADDRS_PER_BLOCK);
}

void VnodeF2fs::TruncatePartialDataPage(uint64_t from) {
  unsigned offset = from & (kPageCacheSize - 1);
  Page *page = nullptr;

  if (!offset)
    return;

  if (FindDataPage(from >> kPageCacheShift, &page) != ZX_OK)
    return;

#if 0  // porting needed
  // lock_page(page);
#endif
  WaitOnPageWriteback(page);
  zero_user(page, offset, kPageCacheSize - offset);
#if 0  // porting needed
  // set_page_dirty(page);
#else
  FlushDirtyDataPage(Vfs(), page);
#endif
  F2fsPutPage(page, 1);
}

#if 0  // porting needed
// int VnodeF2fs::TruncateBlocks(uint64_t from) {
//   f2fs_sb_info &sbi = Vfs()->SbInfo();
//   unsigned int blocksize = sbi.blocksize;
//   dnode_of_data dn;
//   pgoff_t free_from;
//   int count = 0;
//   int err;

//   free_from = (pgoff_t)((from + blocksize - 1) >> (sbi.log_blocksize));

//   mutex_lock_op(&sbi, DATA_TRUNC);

//   SetNewDnode(&dn, this, NULL, NULL, 0);
//   err = Vfs()->Nodemgr().GetDnodeOfData(&dn, free_from, RDONLY_NODE);
//   if (err) {
//     if (err == ZX_ERR_NOT_FOUND)
//       goto free_next;
//     mutex_unlock_op(&sbi, DATA_TRUNC);
//     return err;
//   }

//   if (IS_INODE(dn.node_page))
//     count = ADDRS_PER_INODE;
//   else
//     count = ADDRS_PER_BLOCK;

//   count -= dn.ofs_in_node;
//   BUG_ON(count < 0);
//   if (dn.ofs_in_node || IS_INODE(dn.node_page)) {
//     TruncateDataBlocksRange(&dn, count);
//     free_from += count;
//   }

//   F2fsPutDnode(&dn);
// free_next:
//   err = Vfs()->Nodemgr().TruncateInodeBlocks(this, free_from);
//   mutex_unlock_op(&sbi, DATA_TRUNC);

//   /* lastly zero out the first data page */
//   TruncatePartialDataPage(from);

//   return err;
// }
#endif

zx_status_t VnodeF2fs::TruncateHole(pgoff_t pg_start, pgoff_t pg_end) {
  pgoff_t index;

  for (index = pg_start; index < pg_end; index++) {
    dnode_of_data dn;
    f2fs_sb_info &sbi = Vfs()->SbInfo();

    fbl::AutoLock lock(&sbi.fs_lock[DATA_TRUNC]);
    SetNewDnode(&dn, this, NULL, NULL, 0);
    if (zx_status_t err = Vfs()->Nodemgr().GetDnodeOfData(&dn, index, RDONLY_NODE); err != ZX_OK) {
      if (err == ZX_ERR_NOT_FOUND)
        continue;
      return err;
    }

    if (dn.data_blkaddr != NULL_ADDR)
      TruncateDataBlocksRange(&dn, 1);
    F2fsPutDnode(&dn);
  }
  return ZX_OK;
}

/**
 * Called at the last Iput() if i_nlink is zero
 */
#if 0  // porting needed
// void VnodeF2fs::F2fsEvictInode() {
//   f2fs_sb_info &sbi = Vfs()->SbInfo();

//   // truncate_inode_pages(&inode->i_data, 0);

//   if (ino_ == F2FS_NODE_INO(&sbi) || ino_ == F2FS_META_INO(&sbi))
//     goto no_delete;

//   // BUG_ON(AtomicRead(&fi.->dirty_dents));
//   // remove_dirty_dir_inode(this);

//   if (i_nlink || IsBadInode(this))
//     goto no_delete;

//   SetInodeFlag(&fi, FI_NO_ALLOC);
//   i_size = 0;

//   if (F2FS_HAS_BLOCKS(this))
//     F2fsTruncate();

//   // remove_inode_page(inode);
// no_delete:
//   ClearInode(this);
// }
#endif

void VnodeF2fs::IncNlink() { i_nlink_++; }

void VnodeF2fs::DropNlink() { i_nlink_--; }

void VnodeF2fs::ClearNlink() { i_nlink_ = 0; }

void VnodeF2fs::SetNlink(uint32_t nlink) { i_nlink_ = nlink; }

void MarkInodeDirty(VnodeF2fs *vnode) { vnode->WriteInode(nullptr); }

void VnodeF2fs::Sync(SyncCallback closure) {
	File *file;

  if (closure) {
    if (S_ISDIR(this->i_mode_)) {
      std::cout << "Sync: Invalid args(fsync to directory)" << std::endl;
      closure(ZX_ERR_INVALID_ARGS);
    } else {
      file = static_cast<File *>(this);
      file->SyncFile(0, file->i_size_, 1);
      closure(ZX_OK);
    }
  }
}

zx_status_t VnodeF2fs::QueryFilesystem(::fuchsia_io::wire::FilesystemInfo *info) {
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  *info = {};
  info->block_size = kF2fsBlockSize;
  info->max_filename_size = F2FS_MAX_NAME_LEN;
  info->fs_type = VFS_TYPE_F2FS;
  info->fs_id = Vfs()->FsId();
  info->total_bytes = sbi.user_block_count * kF2fsBlockSize;
  info->used_bytes = valid_user_blocks(&sbi) * kF2fsBlockSize;
  info->total_nodes = sbi.total_node_count;
  info->used_nodes = sbi.total_valid_inode_count;

  constexpr std::string_view kFsName = "f2fs";
  static_assert(kFsName.size() + 1 < ::fuchsia_io::wire::MAX_FS_NAME_BUFFER, "F2fs name too long");
  info->name[kFsName.copy(reinterpret_cast<char *>(info->name.data()),
                          ::fuchsia_io::wire::MAX_FS_NAME_BUFFER - 1)] = '\0';

  // TODO(unknown): Fill info->free_shared_pool_bytes using fvm info

  return ZX_OK;
}

}  // namespace f2fs
