// 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_F2FS_H_
#define THIRD_PARTY_F2FS_F2FS_H_

// clang-format off
#include <lib/zircon-internal/fnv1hash.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <zircon/assert.h>
#include <zircon/device/vfs.h>
#include <zircon/errors.h>
#include <zircon/listnode.h>
#include <zircon/types.h>

#include <iostream>

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

#include "src/lib/storage/vfs/cpp/managed_vfs.h"
#include "src/lib/storage/vfs/cpp/vfs.h"
#include "src/lib/storage/vfs/cpp/vnode.h"
#include "src/lib/storage/vfs/cpp/watcher.h"

#include "f2fs_types.h"
#include "f2fs_lib.h"
#include "f2fs_layout.h"
#include "f2fs_internal.h"
#include "bcache.h"
#include "vnode.h"
#include "dir.h"
#include "file.h"
#include "node.h"
#include "segment.h"
#include "mkfs.h"
// clang-format on

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);
#endif
  loff_t MaxFileSize(unsigned bits);
  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_ __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  // THIRD_PARTY_F2FS_F2FS_H_
