// 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;
//   //   // f2fs_sb_info &sbi = Vfs()->SbInfo();
//   //   Page *node_page;
//   //   block_t old_blk_addr;
//   //   dnode_of_data dn;
//   //   int err;

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

//   //   sb_start_pagefault(nullptr);

//   //   // mutex_lock_op(sbi, DATA_NEW);

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

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

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

//   //   // mutex_unlock_op(sbi, DATA_NEW);

//   //   // 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(f2fs_sb_info *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::F2fsSyncFile(loff_t start, loff_t end, int datasync) {
  f2fs_sb_info &sbi = Vfs()->SbInfo();
  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(F2FS_CKPT(&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 (is_inode_flag_set(&fi, FI_NEED_CP))
    need_cp = true;
  if (!Vfs()->SpaceForRollForward())
    need_cp = true;
  if (NeedToSyncDir(&sbi, this))
    need_cp = true;

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

  // TODO(unknown): fsync recovery
#if 0  // porting needed
  // if (need_cp) {
#else
  if (true) {
#endif
    F2fsWriteInode(nullptr);
    /* all the dirty node pages should be flushed for POR */
    ret = Vfs()->F2fsSyncFs(1);
    ClearInodeFlag(&fi, FI_NEED_CP);
  } 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)
    //   F2fsWriteInode(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) {
//   f2fs_sb_info &sbi = Vfs()->SbInfo();
//   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++) {
//     dnode_of_data dn;

//     mutex_lock_op(&sbi, DATA_NEW);

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

//     if (dn.data_blkaddr == NULL_ADDR) {
//       ret = ReserveNewBlock(&dn);
//       if (ret) {
//         F2fsPutDnode(&dn);
//         mutex_unlock_op(&sbi, DATA_NEW);
//         break;
//       }
//     }
//     F2fsPutDnode(&dn);

//     mutex_unlock_op(&sbi, DATA_NEW);

//     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().F2fsBalanceFs();
//   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;
  //   f2fs_inode_info *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 / kF2fsBlockSize;
  uint64_t blk_end = (off + len) / kF2fsBlockSize;
  size_t off_in_block = off % kF2fsBlockSize;
  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 + kF2fsBlockSize - 1) / kF2fsBlockSize;

  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>(kF2fsBlockSize - off_in_block), left);
    if (n == npages - 1) {
      if (i_size % kF2fsBlockSize > 0)
        cur_len = std::min(cur_len, static_cast<size_t>(i_size % kF2fsBlockSize));
    }

    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 / kF2fsBlockSize;
  uint64_t blk_end = (offset + len) / kF2fsBlockSize;
  size_t off_in_block = offset % kF2fsBlockSize;
  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>(kF2fsBlockSize - off_in_block), left);
    if (zx_status_t ret = F2fsWriteBegin(n * kF2fsBlockSize + 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
