// 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, SuperBlock *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, NodeInfo *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_;

  SuperBlock &RawSb() { return *raw_sb_; }
  SbInfo &GetSbInfo() { 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(PageType 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();
  FsyncInodeEntry *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, CursegType 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<SuperBlock> raw_sb_;
  std::unique_ptr<SbInfo> 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_
