// 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 <algorithm>
#include <sys/stat.h>
#include "f2fs.h"

namespace f2fs {

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

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

#if 0  // porting needed
// int File::F2fsVmPageMkwrite(vm_area_struct *vma, vm_fault *vmf) {
//   return 0;
//   //   Page *page = vmf->page;
//   //   VnodeF2fs *vnode = this;
//   //   // SbInfo &sbi = Vfs()->GetSbInfo();
//   //   Page *node_page;
//   //   block_t old_blk_addr;
//   //   DnodeOfData dn;
//   //   int err;

//   //   Vfs()->Segmgr().BalanceFs();

//   //   sb_start_pagefault(nullptr);

//   //   // mutex_lock_op(sbi, LockType::kDataNew);

//   //   /* block allocation */
//   //   SetNewDnode(&dn, vnode, NULL, NULL, 0);
//   //   err = Vfs()->Nodemgr().GetDnodeOfData(&dn, page->index, 0);
//   //   if (err) {
//   //     // mutex_unlock_op(sbi, LockType::kDataNew);
//   //     goto out;
//   //   }

//   //   old_blk_addr = dn.data_blkaddr;
//   //   node_page = dn.node_page;

//   //   if (old_blk_addr == kNullAddr) {
//   //     err = VnodeF2fs::ReserveNewBlock(&dn);
//   //     if (err) {
//   //       F2fsPutDnode(&dn);
//   //       // mutex_unlock_op(sbi, LockType::kDataNew);
//   //       goto out;
//   //     }
//   //   }
//   //   F2fsPutDnode(&dn);

//   //   // mutex_unlock_op(sbi, LockType::kDataNew);

//   //   // lock_page(page);
//   //   // if (page->mapping != inode->i_mapping ||
//   //   //     page_offset(page) >= i_size_read(inode) ||
//   //   //     !PageUptodate(page)) {
//   //   //   unlock_page(page);
//   //   //   err = -EFAULT;
//   //   //   goto out;
//   //   // }

//   //   /*
//   //    * check to see if the page is mapped already (no holes)
//   //    */
//   //   if (PageMappedToDisk(page))
//   //     goto out;

//   //   /* fill the page */
//   //   WaitOnPageWriteback(page);

//   //   /* page is wholly or partially inside EOF */
//   //   if (((page->index + 1) << kPageCacheShift) > i_size) {
//   //     unsigned offset;
//   //     offset = i_size & ~PAGE_CACHE_MASK;
//   //     ZeroUserSegment(page, offset, kPageCacheSize);
//   //   }
//   //   // set_page_dirty(page);
//   //   FlushDirtyDataPage(Vfs(), page);
//   //   SetPageUptodate(page);

//   //   file_update_time(vma->vm_file);
//   // out:
//   //   sb_end_pagefault(nullptr);
//   //   return block_page_mkwrite_return(err);
// }
#endif

int File::NeedToSyncDir(SbInfo *sbi, VnodeF2fs *vnode) {
#if 0  // porting needed
  // dentry *dentry;
#endif
  nid_t pino = 0;

  vnode = static_cast<VnodeF2fs *>(Igrab((void *)vnode));
#if 0  // porting needed
  // dentry = d_find_any_alias(vnode);
  // if (!dentry) {
    //   // Iput(inode);
  //   return 0;
  // }
  // pino = dentry->d_parent->d_inode->i_ino;
  // dput(dentry);
#endif
  Iput(vnode);
  return !Vfs()->Nodemgr().IsCheckpointedNode(pino);
}

zx_status_t File::SyncFile(loff_t start, loff_t end, int datasync) {
  SbInfo &sbi = Vfs()->GetSbInfo();
  uint64_t cur_version;
  zx_status_t ret = 0;
  bool need_cp = false;
#if 0  // porting needed
  // WritebackControl wbc;

  // wbc.sync_mode = WB_SYNC_ALL;
  // wbc.nr_to_write = LONG_MAX;
  // wbc.for_reclaim = 0;

  // ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
  // if (ret)
  //   return ret;
#endif

  fbl::AutoLock lock(&i_mutex_);

#if 0  // porting needed
  // if (inode->i_sb->s_flags & MS_RDONLY)
  //   goto out;
  // if (datasync && !(i_state & I_DIRTY_DATASYNC)) {
  //  goto out;
  //}
#endif

  do {
    fbl::AutoLock cplock(&sbi.cp_mutex);
    cur_version = LeToCpu(GetCheckpoint(&sbi)->checkpoint_ver);
  } while(false);

#if 0  // porting needed
  // if (fi.data_version != cur_version &&
  //        !(i_state & I_DIRTY)) {
  //  goto out;
  //}
#endif
  fi_.data_version--;

  if (!S_ISREG(i_mode_) || i_nlink_ != 1)
    need_cp = true;
  if (IsInodeFlagSet(&fi_, InodeInfoFlag::kFiNeedCp))
    need_cp = true;
  if (!Vfs()->SpaceForRollForward())
    need_cp = true;
  if (NeedToSyncDir(&sbi, this))
    need_cp = true;

#if 0  // porting needed
  // WriteInode(nullptr);
#endif

  // TODO(unknown): fsync recovery
#if 0  // porting needed
  // if (need_cp) {
#else
  if (true) {
#endif
    WriteInode(nullptr);
    /* all the dirty node pages should be flushed for POR */
    ret = Vfs()->SyncFs(1);
    ClearInodeFlag(&fi_, InodeInfoFlag::kFiNeedCp);
  } else {
    Page *node_page = nullptr;
    int mark = !Vfs()->Nodemgr().IsCheckpointedNode(Ino());
    if (ret = Vfs()->Nodemgr().GetNodePage(Ino(), &node_page); ret != ZX_OK) {
      return ret;
    }

    Vfs()->Nodemgr().SetFsyncMark(node_page, 1);
    Vfs()->Nodemgr().SetDentryMark(node_page, mark);

    UpdateInode(node_page);
    F2fsPutPage(node_page, 1);

#if 0  // porting needed
    // while (Vfs()->Nodemgr().SyncNodePages(Ino(), &wbc) == 0)
    //   WriteInode(nullptr);
    // filemap_fdatawait_range(nullptr,//sbi->node_inode->i_mapping,
    //           0, LONG_MAX);
#endif
  }
#if 0  // porting needed
  // out:
#endif
  return ret;
}

#if 0  // porting needed
// int File::F2fsFileMmap(/*file *file,*/ vm_area_struct *vma) {
//   // file_accessed(file);
//   // vma->vm_ops = &f2fs_file_vm_ops;
//   return 0;
// }

// void File::FillZero(pgoff_t index, loff_t start, loff_t len) {
//   Page *page = nullptr;
//   zx_status_t err;

//   if (!len)
//     return;

//   err = GetNewDataPage(index, false, page);

//   if (!err) {
//     WaitOnPageWriteback(page);
//     zero_user(page, start, len);
// #if 0  // porting needed
//     // set_page_dirty(page);
// #else
//     FlushDirtyDataPage(Vfs(), page);
// #endif
//     F2fsPutPage(page, 1);
//   }
// }

// int File::PunchHole(loff_t offset, loff_t len, int mode) {
//   pgoff_t pg_start, pg_end;
//   loff_t off_start, off_end;
//   int ret = 0;

//   pg_start = ((uint64_t)offset) >> kPageCacheShift;
//   pg_end = ((uint64_t)offset + len) >> kPageCacheShift;

//   off_start = offset & (kPageCacheSize - 1);
//   off_end = (offset + len) & (kPageCacheSize - 1);

//   if (pg_start == pg_end) {
//     FillZero(pg_start, off_start, off_end - off_start);
//   } else {
//     if (off_start)
//       FillZero(pg_start++, off_start, kPageCacheSize - off_start);
//     if (off_end)
//       FillZero(pg_end, 0, off_end);

//     if (pg_start < pg_end) {
//       loff_t blk_start, blk_end;

//       blk_start = pg_start << kPageCacheShift;
//       blk_end = pg_end << kPageCacheShift;
// #if 0  // porting needed
//       // truncate_inode_pages_range(nullptr, blk_start,
//       //     blk_end - 1);
// #endif
//       ret = TruncateHole(pg_start, pg_end);
//     }
//   }

//   if (!(mode & FALLOC_FL_KEEP_SIZE) && i_size <= (offset + len)) {
//     i_size = offset;
//     MarkInodeDirty(this);
//   }

//   return ret;
// }

// int File::ExpandInodeData(loff_t offset, off_t len, int mode) {
//   SbInfo &sbi = Vfs()->GetSbInfo();
//   pgoff_t index, pg_start, pg_end;
//   loff_t new_size = i_size;
//   loff_t off_start, off_end;
//   int ret = 0;

// #if 0  // porting needed
//   // ret = inode_newsize_ok(this, (len + offset));
//   // if (ret)
//   //   return ret;
// #endif

//   pg_start = ((uint64_t)offset) >> kPageCacheShift;
//   pg_end = ((uint64_t)offset + len) >> kPageCacheShift;

//   off_start = offset & (kPageCacheSize - 1);
//   off_end = (offset + len) & (kPageCacheSize - 1);

//   for (index = pg_start; index <= pg_end; index++) {
//     DnodeOfData dn;

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

//     SetNewDnode(&dn, this, NULL, NULL, 0);
//     ret = Vfs()->Nodemgr().GetDnodeOfData(&dn, index, 0);
//     if (ret) {
//       mutex_unlock_op(&sbi, LockType::kDataNew);
//       break;
//     }

//     if (dn.data_blkaddr == kNullAddr) {
//       ret = ReserveNewBlock(&dn);
//       if (ret) {
//         F2fsPutDnode(&dn);
//         mutex_unlock_op(&sbi, LockType::kDataNew);
//         break;
//       }
//     }
//     F2fsPutDnode(&dn);

//     mutex_unlock_op(&sbi, LockType::kDataNew);

//     if (pg_start == pg_end)
//       new_size = offset + len;
//     else if (index == pg_start && off_start)
//       new_size = (index + 1) << kPageCacheShift;
//     else if (index == pg_end)
//       new_size = (index << kPageCacheShift) + off_end;
//     else
//       new_size += kPageCacheSize;
//   }

//   if (!(mode & FALLOC_FL_KEEP_SIZE) && i_size < new_size) {
//     i_size = new_size;
//     MarkInodeDirty(this);
//   }

//   return ret;
// }

// long File::F2fsFallocate(int mode, loff_t offset, loff_t len) {
//   long ret;

//   if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
//     return -EOPNOTSUPP;

//   if (mode & FALLOC_FL_PUNCH_HOLE)
//     ret = PunchHole(offset, len, mode);
//   else
//     ret = ExpandInodeData(offset, len, mode);

//   Vfs()->Segmgr().BalanceFs();
//   return ret;
// }

// #define F2FS_REG_FLMASK    (~(FS_DIRSYNC_FL | FS_TOPDIR_FL))
// #define F2FS_OTHER_FLMASK  (FS_NODUMP_FL | FS_NOATIME_FL)

// inline uint32_t File::F2fsMaskFlags(umode_t mode, uint32_t flags) {
//   if (S_ISDIR(mode))
//     return flags;
//   else if (S_ISREG(mode))
//     return flags & F2FS_REG_FLMASK;
//   else
//     return flags & F2FS_OTHER_FLMASK;
// }

// long File::F2fsIoctl(/*file *filp,*/ unsigned int cmd, uint64_t arg) {
  //   inode *inode = filp->f_dentry->d_inode;
  //   InodeInfo *fi = F2FS_I(inode);
  //   unsigned int flags;
  //   int ret;

  //   switch (cmd) {
  //   case FS_IOC_GETFLAGS:
  //     flags = fi->i_flags & FS_FL_USER_VISIBLE;
  //     return put_user(flags, (int __user *) arg);
  //   case FS_IOC_SETFLAGS:
  //   {
  //     unsigned int oldflags;

  //     ret = mnt_want_write(filp->f_path.mnt);
  //     if (ret)
  //       return ret;

  //     if (!inode_owner_or_capable(inode)) {
  //       ret = -EACCES;
  //       goto out;
  //     }

  //     if (get_user(flags, (int __user *) arg)) {
  //       ret = -EFAULT;
  //       goto out;
  //     }

  //     flags = f2fs_mask_flags(inode->i_mode, flags);

  //     mutex_lock(&inode->i_mutex_);

  //     oldflags = fi->i_flags;

  //     if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
  //       if (!capable(CAP_LINUX_IMMUTABLE)) {
  //         mutex_unlock(&inode->i_mutex_);
  //         ret = -EPERM;
  //         goto out;
  //       }
  //     }

  //     flags = flags & FS_FL_USER_MODIFIABLE;
  //     flags |= oldflags & ~FS_FL_USER_MODIFIABLE;
  //     fi->i_flags = flags;
  //     mutex_unlock(&inode->i_mutex_);

  //     f2fs_set_inode_flags(inode);
  //     inode->i_ctime = CURRENT_TIME;
  //     MarkInodeDirty(inode);
  // out:
  //     mnt_drop_write(filp->f_path.mnt);
  //     return ret;
  //   }
  //   default:
  //     return -ENOTTY;
  //   }
// }
#endif


zx_status_t File::Read(void *data, size_t len, size_t off, size_t *out_actual) {
  uint64_t blk_start = off / kBlockSize;
  uint64_t blk_end = (off + len) / kBlockSize;
  size_t off_in_block = off % kBlockSize;
  size_t off_in_buf = 0;
  Page *data_page = nullptr;
  void *data_buf = nullptr;
  uint64_t n;
  size_t left = len;
  uint64_t npages = (i_size_ + kBlockSize - 1) / kBlockSize;

  fbl::AutoLock lock(&i_mutex_);

  if (off >= i_size_) {
    *out_actual = 0;
    return ZX_OK;
  }

  for (n = blk_start; n <= blk_end; n++) {
    if (zx_status_t ret = GetLockDataPage(n, &data_page); ret != ZX_OK) {
      *out_actual = off_in_buf;
      return ret;
    }

    size_t cur_len = std::min(static_cast<size_t>(kBlockSize - off_in_block), left);
    if (n == npages - 1) {
      if (i_size_ % kBlockSize > 0)
        cur_len = std::min(cur_len, static_cast<size_t>(i_size_ % kBlockSize));
    }

    data_buf = PageAddress(data_page);
    memcpy(static_cast<char *>(data) + off_in_buf, data_buf, cur_len);

    off_in_buf += cur_len;
    left -= cur_len;
    off_in_block = 0;

    F2fsPutPage(data_page, 1);
    data_page = nullptr;

    if (left == 0)
      break;

    if (n == npages - 1)
      break;
  }

  *out_actual = off_in_buf;

  return ZX_OK;
}

zx_status_t File::Write(const void *data, size_t len, size_t offset, size_t *out_actual) {
  uint64_t blk_start = offset / kBlockSize;
  uint64_t blk_end = (offset + len) / kBlockSize;
  size_t off_in_block = offset % kBlockSize;
  size_t off_in_buf = 0;
  Page *data_page = nullptr;
  void *data_buf = nullptr;
  uint64_t n;
  size_t left = len;

  fbl::AutoLock lock(&i_mutex_);

  for (n = blk_start; n <= blk_end; n++) {
    size_t cur_len = std::min(static_cast<size_t>(kBlockSize - off_in_block), left);
    if (zx_status_t ret = WriteBegin(n * kBlockSize + off_in_block, cur_len, &data_page); ret != ZX_OK) {
      if (off_in_buf > 0) {
        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);
      }
      *out_actual = off_in_buf;

      return ret;
    }

    data_buf = PageAddress(data_page);
    memcpy(static_cast<char *>(data_buf) + off_in_block, static_cast<const char *>(data) + off_in_buf, cur_len);

    off_in_buf += cur_len;
    left -= cur_len;
    off_in_block = 0;

    i_size_ = std::max(static_cast<size_t>(i_size_), offset + off_in_buf);
#if 0  // porting needed
    // set_page_dirty(data_page, Vfs());
#else
    FlushDirtyDataPage(Vfs(), data_page);
#endif
    F2fsPutPage(data_page, 1);
    data_page = nullptr;

    if (left == 0)
      break;
  }

  if (off_in_buf > 0) {
    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);
  }
  *out_actual = off_in_buf;

  return ZX_OK;
}

}  // namespace f2fs
