// 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.

#ifndef THIRD_PARTY_F2FS_VNODE_H_
#define THIRD_PARTY_F2FS_VNODE_H_

#include "namestring.h"

namespace f2fs {

// Used by fsck
class F2fs;

class VnodeF2fs : public fs::Vnode,
                  public fbl::SinglyLinkedListable<VnodeF2fs *>,
                  public fbl::Recyclable<VnodeF2fs> {
 public:
  explicit VnodeF2fs(F2fs *fs);
  explicit VnodeF2fs(F2fs *fs, ino_t ino);
  ~VnodeF2fs() = default;

  static void Allocate(F2fs *fs, ino_t ino, uint32_t mode, fbl::RefPtr<VnodeF2fs> *out);
  static void Create(F2fs *fs, ino_t ino, fbl::RefPtr<VnodeF2fs> *out);

  ino_t GetKey() const { return ino_; }

  static size_t GetHash(ino_t key) { return fnv1a_tiny(key, kHashBits); }

  using fs::Vnode::Open;
  zx_status_t Open(ValidatedOptions options, fbl::RefPtr<Vnode> *out_redirect);
  zx_status_t Close();

  void Sync(SyncCallback closure) final;
  zx_status_t SyncFile(loff_t start, loff_t end, int datasync);
  int NeedToSyncDir(SbInfo *sbi, VnodeF2fs *vnode);

  zx_status_t QueryFilesystem(fuchsia_io::wire::FilesystemInfo *info) final;

  void fbl_recycle() { RecycleNode(); };

  bool IsDirectory();

  F2fs *Vfs() const { return fs_; }
  ino_t Ino() const { return ino_; }
  Inode GetInode() const { return inode_; }

  zx_status_t GetAttributes(fs::VnodeAttributes *a) final;
  zx_status_t SetAttributes(fs::VnodeAttributesUpdate attr) final;

  zx_status_t GetNodeInfoForProtocol([[maybe_unused]] fs::VnodeProtocol protocol,
                                     [[maybe_unused]] fs::Rights rights,
                                     fs::VnodeRepresentation *info) final;

  fs::VnodeProtocolSet GetProtocols() const final;

#if 0  // porting needed
  // void F2fsSetInodeFlags();
  // int F2fsIgetTest(void *data);
  // VnodeF2fs *F2fsIgetNowait(uint64_t ino);
#endif

  static zx_status_t Vget(F2fs *fs, uint64_t ino, fbl::RefPtr<VnodeF2fs> *out);
  void UpdateInode(Page *node_page);
  zx_status_t WriteInode(WritebackControl *wbc);
  zx_status_t DoTruncate();
  int TruncateDataBlocksRange(DnodeOfData *dn, int count);
  void TruncateDataBlocks(DnodeOfData *dn);
  void TruncatePartialDataPage(uint64_t from);
  zx_status_t TruncateBlocks(uint64_t from);
  zx_status_t TruncateHole(pgoff_t pg_start, pgoff_t pg_end);
#if 0  // porting needed
  // void F2fsEvictInode();
#endif

  void SetDataBlkaddr(DnodeOfData *dn, block_t new_addr);
  int ReserveNewBlock(DnodeOfData *dn);

#if 0  // porting needed
  // static int CheckExtentCache(inode *inode, pgoff_t pgofs,
  //        buffer_head *bh_result);
#endif
  void UpdateExtentCache(block_t blk_addr, DnodeOfData *dn);
  zx_status_t FindDataPage(pgoff_t index, Page **out);
  zx_status_t GetLockDataPage(pgoff_t index, Page **out);
  zx_status_t GetNewDataPage(pgoff_t index, bool new_i_size, Page **out);

  static zx_status_t Readpage(F2fs *fs, Page *page, block_t blk_addr, int type);
#if 0  // porting needed
  // static int GetDataBlockRo(inode *inode, sector_t iblock,
  //      buffer_head *bh_result, int create);
  // static int F2fsReadDataPage(file *file, page *page);
  // static int F2fsReadDataPages(file *file,
  //       address_space *mapping,
  //       list_head *pages, unsigned nr_pages);
#endif
  zx_status_t DoWriteDataPage(Page *page);
  zx_status_t WriteDataPageReq(Page *page, WritebackControl *wbc);
#if 0  // porting needed
  // int F2fsWriteDataPages(/*address_space *mapping,*/
  //                        WritebackControl *wbc);
#endif
  zx_status_t WriteBegin(size_t pos, size_t len, Page **page);
#if 0  // porting needed
  // ssize_t F2fsDirectIO(/*int rw, kiocb *iocb,
  //   const iovec *iov, */
  //                      loff_t offset, uint64_t nr_segs);
  //   [[maybe_unused]] static void F2fsInvalidateDataPage(Page *page, uint64_t offset);
  //   [[maybe_unused]] static int F2fsReleaseDataPage(Page *page, gfp_t wait);
  // int F2fsSetDataPageDirty(Page *page);
#endif

  void IncNlink();
  void DropNlink();
  void ClearNlink();
  void SetNlink(uint32_t nlink);

  uint64_t GetBlocks();

  void Notify(std::string_view name, unsigned event) final;
  zx_status_t WatchDir(fs::Vfs *vfs, uint32_t mask, uint32_t options, zx::channel watcher) final;

  // TODO(unknown): non-public member variables
  fbl::Mutex v_lock_;
  mtx_t i_mutex_;

  umode_t i_mode_;
  uid_t i_uid_;
  gid_t i_gid_;
  unsigned int i_nlink_;

  uint64_t i_size_;
  blkcnt_t i_blocks_;
  timespec i_atime_;
  timespec i_mtime_;
  timespec i_ctime_;
  uint32_t i_generation_;

  uint64_t i_state_;

  NameString i_name_sp_;

  InodeInfo fi_;

 protected:
  void RecycleNode() override;

 private:
  F2fs *fs_;
  ino_t ino_{};
  Inode inode_{};
  uint32_t fd_count_{};
  fs::WatcherContainer watcher_{};
};

void MarkInodeDirty(VnodeF2fs *vnode);

}  // namespace f2fs

#endif  // THIRD_PARTY_F2FS_VNODE_H_
