// 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 F2FS_H_
#define F2FS_H_

#include <zircon/types.h>
#include <zircon/errors.h>
#include <zircon/assert.h>
#include <zircon/listnode.h>

#include <iostream>

#include <fbl/algorithm.h>
#include <fbl/function.h>
#include <fbl/intrusive_hash_table.h>
#include <fbl/intrusive_single_list.h>
#include <fbl/macros.h>
#include <fbl/ref_ptr.h>
#include <fbl/mutex.h>
#include <fbl/auto_lock.h>

#include <zircon/device/vfs.h>
#include "src/lib/storage/vfs/cpp/vfs.h"
#include "src/lib/storage/vfs/cpp/vnode.h"
#include "src/lib/storage/vfs/cpp/managed_vfs.h"

#include <lib/zircon-internal/thread_annotations.h>
#include <lib/zircon-internal/fnv1hash.h>

#include "f2fs_types.h"
#include "f2fs_lib.h"
#include "f2fs_layout.h"
#include "f2fs_internal.h"
#include "vnode.h"
#include "dir.h"
#include "file.h"
#include "bcache.h"
#include "mkfs.h"
#include "segment.h"
#include "node.h"



namespace f2fs {

struct MountOptions {
  bool background_gc = false;
  bool disable_roll_forward = true;
  bool discard = false;
  bool noheap = true;
  bool xattr_user = false;
  bool posix_acl = false;
  bool disable_ext_identify = true;
  uint32_t active_logs = 6;
};

enum class ServeLayout {
  // The root of the filesystem is exposed directly.
  kDataRootOnly,

  // Expose a pseudo-directory with the filesystem root located at "svc/root".
  // TODO(fxbug.dev/34531): Also expose an administration service under "svc/fuchsia.fs.Admin".
  kExportDirectory
};

zx_status_t Mkfs(const MkfsOptions &options, std::unique_ptr<f2fs::Bcache> bc);
zx_status_t Fsck(const MountOptions &options, std::unique_ptr<f2fs::Bcache> bc);
zx_status_t Mount(const MountOptions &options, std::unique_ptr<f2fs::Bcache> bc);

zx_status_t CreateBcache(std::unique_ptr<block_client::BlockDevice> device, bool *out_readonly,
                         std::unique_ptr<f2fs::Bcache> *out);

using SyncCallback = fs::Vnode::SyncCallback;

class F2fs : public fs::ManagedVfs {
 public:
  // Not copyable or moveable
  F2fs(const F2fs &) = delete;
  F2fs &operator=(const F2fs &) = delete;
  F2fs(F2fs &&) = delete;
  F2fs &operator=(F2fs &&) = delete;

  explicit F2fs(std::unique_ptr<f2fs::Bcache> bc, f2fs_super_block *sb, const MountOptions &mount_options);

  ~F2fs() override;

  [[nodiscard]] static zx_status_t Create(std::unique_ptr<f2fs::Bcache> bc,
                                          const MountOptions &options, std::unique_ptr<F2fs> *out);

  void InsertVnode(VnodeF2fs *vn);
  void EraseVnodeFromTable(VnodeF2fs *vn);

  zx_status_t FindVnode(fbl::RefPtr<VnodeF2fs> *out, ino_t ino);

  void GetNodeInfo(nid_t nid, struct node_info *ni);

  void SetUnmountCallback(fbl::Closure closure) { on_unmount_ = std::move(closure); }
  void Shutdown(fs::Vfs::ShutdownCallback cb) final;

  std::unique_ptr<f2fs::Bcache> bc_;

  f2fs_super_block &RawSb() { return *raw_sb_; }
  f2fs_sb_info &SbInfo() { return *sbi_; }
  SegMgr &Segmgr() { return *seg_mgr_; }
  NodeMgr &Nodemgr() { return *node_mgr_; }

  uint64_t FsId() const { return fs_id_; }

#if 0  // porting needed
  // void InitOnce(void *foo);
  // VnodeF2fs *F2fsAllocInode();
  // static void F2fsICallback(struct rcu_head *head);
  // void F2fsDestroyInode(struct inode *inode);
#endif

  void F2fsPutSuper();
  int F2fsSyncFs(int sync);
#if 0  // porting needed
  // int F2fsStatfs(struct dentry *dentry /*, struct kstatfs *buf*/);
  // int F2fsShowOptions(/*struct seq_file *seq*/);
  // VnodeF2fs *F2fsNfsGetInode(uint64_t ino, uint32_t generation);
  // struct dentry *F2fsFhToDentry(struct fid *fid, int fh_len, int fh_type);
  // struct dentry *F2fsFhToParent(struct fid *fid, int fh_len, int fh_type);
  // int ParseOptions(char *options);
  // loff_t MaxFileSize(unsigned bits);
#endif
  int SanityCheckRawSuper();
  int SanityCheckCkpt();
  void InitSbInfo();
  zx_status_t F2fsFillSuper();
#if 0  // porting needed
  // struct dentry *F2fsMount(struct file_system_type *fs_type, int flags,
  //     const char *dev_name, void *data);
  // int InitInodecache(void);
  // void DestroyInodecache(void);
  // int /*__init*/ initF2fsFs(void);
  // void /*__exit*/ exitF2fsFs(void);
#endif

  // checkpoint.cc
  Page *GetMetaPage(pgoff_t index);
  Page *GrabMetaPage(pgoff_t index);
  int F2fsWriteMetaPage(Page *page, struct WritebackControl *wbc);
#if 0  // porting needed
  // int F2fsWriteMetaPages(struct address_space *mapping, struct WritebackControl *wbc);
#endif
  long SyncMetaPages(enum page_type type, long nr_to_write);
#if 0  // porting needed
  // int F2fsSetMetaPageDirty(Page *page);
#endif
  int CheckOrphanSpace();
  void AddOrphanInode(nid_t ino);
  void RemoveOrphanInode(nid_t ino);
  void RecoverOrphanInode(nid_t ino);
  int RecoverOrphanInodes();
  void WriteOrphanInodes(block_t start_blk);
  zx_status_t GetValidCheckpoint();
  Page *ValidateCheckpoint(block_t cp_addr, uint64_t *version);
#if 0  // porting needed
  // void SetDirtyDirPage(VnodeF2fs *vnode, Page *page);
  // void RemoveDirtyDirInode(VnodeF2fs *vnode);
#endif
  void SyncDirtyDirInodes();
  void BlockOperations();
  void UnblockOperations();
  void DoCheckpoint(bool is_umount);
  void WriteCheckpoint(bool blocked, bool is_umount);
  void InitOrphanInfo();
#if 0  // porting needed
  int CreateCheckpointCaches();
  void DestroyCheckpointCaches();
#endif

  // recovery.cc
  bool SpaceForRollForward();
  struct fsync_inode_entry *GetFsyncInode(list_node_t *head, nid_t ino);
  zx_status_t RecoverDentry(Page *ipage, VnodeF2fs *vnode);
  zx_status_t RecoverInode(VnodeF2fs *inode, Page *node_page);
  zx_status_t FindFsyncDnodes(list_node_t *head);
  void DestroyFsyncDnodes(list_node_t *head);
  void CheckIndexInPrevNodes(block_t blkaddr);
  void DoRecoverData(VnodeF2fs *inode, Page *page, block_t blkaddr);
  void RecoverData(list_node_t *head, int type);
  void RecoverFsyncData();

 private:
  using HashTable = fbl::HashTable<ino_t, VnodeF2fs *>;
  fbl::Mutex vnode_table_lock_;
  HashTable vnode_table_ FS_TA_GUARDED(vnode_table_lock_){};

  fbl::RefPtr<VnodeF2fs> root_vnode_;

  fbl::Closure on_unmount_{};
  MountOptions mount_options_;

  std::unique_ptr<f2fs_super_block> raw_sb_;
  std::unique_ptr<f2fs_sb_info> sbi_;
  std::unique_ptr<SegMgr> seg_mgr_;
  std::unique_ptr<NodeMgr> node_mgr_;

  uint64_t fs_id_ = 0;
};

f2fs_hash_t F2fsDentryHash(const char *name, int len);

zx_status_t FlushDirtyNodePage(F2fs *fs, Page *page);
zx_status_t FlushDirtyMetaPage(F2fs *fs, Page *page);
zx_status_t FlushDirtyDataPage(F2fs *fs, Page *page);

}  // namespace f2fs

#endif  // F2FS_H_
