// 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->GetSbInfo(), 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(InodeInfo));

#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_, InodeInfoFlag::kFiNewInode);
}

// 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;
  Inode *ri;
  Node *rn;

  if (ino == NodeIno(&fs->GetSbInfo()) || ino == MetaIno(&fs->GetSbInfo())) {
    *out = fbl::AdoptRef(new VnodeF2fs(fs, ino));
    return;
  }

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

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

  rn = static_cast<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(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(GetCheckpoint(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_ * kBlockSize;
  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 == NodeIno(&fs->GetSbInfo()) || ino == MetaIno(&fs->GetSbInfo()))) {
    if (!fs->GetSbInfo().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 == NodeIno(sbi)) {
  //   // inode->i_mapping->a_ops = &Node_aops; //invalidatepage, releasepage
  //   // mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_ZERO);
  // } else if (ino == MetaIno(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) {
  Node *rn;
  Inode *ri;

  WaitOnPageWriteback(node_page);

  rn = static_cast<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 {
  SbInfo &sbi = Vfs()->GetSbInfo();
  Page *node_page = nullptr;
  zx_status_t ret = ZX_OK;

  if (ino_ == NodeIno(&sbi) || ino_ == MetaIno(&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().BalanceFs();
// }
#endif

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

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

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

    UpdateExtentCache(kNullAddr, dn);
    Vfs()->Segmgr().InvalidateBlocks(blkaddr);
    DecValidBlockCount(&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(DnodeOfData *dn) {
  TruncateDataBlocksRange(dn, kAddrsPerBlock);
}

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) {
//   SbInfo &sbi = Vfs()->GetSbInfo();
//   unsigned int blocksize = sbi.blocksize;
//   DnodeOfData dn;
//   pgoff_t free_from;
//   int count = 0;
//   int err;

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

//   mutex_lock_op(&sbi, LockType::kDataTrunc);

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

//   if (IsInode(dn.node_page))
//     count = kAddrsPerInode;
//   else
//     count = kAddrsPerBlock;

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

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

//   /* 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++) {
    DnodeOfData dn;
    SbInfo &sbi = Vfs()->GetSbInfo();

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

    if (dn.data_blkaddr != kNullAddr)
      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() {
//   SbInfo &sbi = Vfs()->GetSbInfo();

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

//   if (ino_ == NodeIno(&sbi) || ino_ == MetaIno(&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, InodeInfoFlag::kFiNoAlloc);
//   i_size = 0;

//   if (HasBlocks(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) {
  SbInfo &sbi = Vfs()->GetSbInfo();
  *info = {};
  info->block_size = kBlockSize;
  info->max_filename_size = kMaxNameLen;
  info->fs_type = VFS_TYPE_F2FS;
  info->fs_id = Vfs()->FsId();
  info->total_bytes = sbi.user_block_count * kBlockSize;
  info->used_bytes = ValidUserBlocks(&sbi) * kBlockSize;
  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
