// 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, node_info *ni);

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

  // TODO(unknown): non-public member variables
  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(rcu_head *head);
  // void F2fsDestroyInode(inode *inode);
#endif

  void PutSuper();
  zx_status_t SyncFs(int sync);
#if 0  // porting needed
  // int F2fsStatfs(dentry *dentry /*, kstatfs *buf*/);
  // int F2fsShowOptions(/*seq_file *seq*/);
  // VnodeF2fs *F2fsNfsGetInode(uint64_t ino, uint32_t generation);
  // dentry *F2fsFhToDentry(fid *fid, int fh_len, int fh_type);
  // dentry *F2fsFhToParent(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 FillSuper();
#if 0  // porting needed
  // dentry *F2fsMount(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);
  zx_status_t F2fsWriteMetaPage(Page *page, WritebackControl *wbc);
#if 0  // porting needed
  // int F2fsWriteMetaPages(address_space *mapping, WritebackControl *wbc);
#endif
  int64_t SyncMetaPages(enum page_type type, long nr_to_write);
#if 0  // porting needed
  // int F2fsSetMetaPageDirty(Page *page);
#endif
  zx_status_t 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();
  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 DentryHash(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_
