// 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);
  int 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
  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();
  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_
