// 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 <sys/stat.h>

#include <algorithm>

#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::kNeedCp))
    need_cp = true;
  if (!Vfs()->SpaceForRollForward())
    need_cp = true;
  if (NeedToSyncDir(&sbi, this))
    need_cp = true;

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

    // clang-format off
    // 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::kNeedCp);
  }
  else {
    Page *node_page = nullptr;
    int mark = !Vfs()->Nodemgr().IsCheckpointedNode(Ino());
    if (ret = Vfs()->Nodemgr().GetNodePage(Ino(), &node_page); ret != ZX_OK) {
      return ret;
  }
  // clang-format on

  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++) {
    bool is_empty_page = false;

    if (zx_status_t ret = GetLockDataPage(n, &data_page); ret != ZX_OK) {
      if (ret == ZX_ERR_NOT_FOUND) {  // truncated page
        is_empty_page = true;
      } else {
        *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));
    }

    if (is_empty_page) {
      memset(static_cast<char *>(data) + off_in_buf, 0, cur_len);
    } else {
      data_buf = PageAddress(data_page);
      memcpy(static_cast<char *>(data) + off_in_buf, static_cast<char *>(data_buf) + off_in_block,
             cur_len);
    }

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

    if (!is_empty_page) {
      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::DoWrite(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;

  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;
}

zx_status_t File::Write(const void *data, size_t len, size_t offset, size_t *out_actual) {
  fbl::AutoLock lock(&i_mutex_);
  return DoWrite(data, len, offset, out_actual);
}

zx_status_t File::Append(const void *data, size_t len, size_t *out_end, size_t *out_actual) {
  fbl::AutoLock lock(&i_mutex_);
  size_t off = i_size_;
  zx_status_t ret = DoWrite(data, len, off, out_actual);

  *out_end = off + *out_actual;

  return ret;
}

zx_status_t File::Truncate(size_t len) {
  if (len == i_size_)
    return ZX_OK;

  if (len > static_cast<size_t>(Vfs()->MaxFileSize(Vfs()->RawSb().log_blocksize)))
    return ZX_ERR_INVALID_ARGS;

  i_size_ = len;

  return DoTruncate();
}

}  // namespace f2fs
