// 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.

#include <numeric>

#include <gtest/gtest.h>
#include <safemath/checked_math.h>

#include "src/storage/f2fs/f2fs.h"
#include "src/storage/lib/block_client/cpp/fake_block_device.h"
#include "unit_lib.h"

namespace f2fs {
namespace {

class VnodeTest : public F2fsFakeDevTestFixture {
 public:
  VnodeTest()
      : F2fsFakeDevTestFixture(TestOptions{
            .mount_options = {{MountOption::kInlineDentry, false}},
        }) {}
};

template <typename T>
void VgetFaultInjetionAndTest(F2fs &fs, Dir &root_dir, std::string_view name, T fault_injection,
                              zx_status_t expected_status) {
  // Create a child
  FileTester::CreateChild(&root_dir, S_IFDIR, name);
  // Log updates on disk
  fs.SyncFs();

  // Check if the child is okay
  fbl::RefPtr<fs::Vnode> vnode;
  FileTester::Lookup(&root_dir, name, &vnode);
  fbl::RefPtr<VnodeF2fs> test_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(std::move(vnode));
  nid_t nid = test_vnode->GetKey();
  ASSERT_FALSE(test_vnode->IsDirty());
  ASSERT_EQ(name, test_vnode->GetNameView());

  // fault injection on the inode page after evicting the child from vnode cache
  ASSERT_EQ(fs.GetVCache().Evict(test_vnode.get()), ZX_OK);
  test_vnode->Close();
  test_vnode.reset();
  {
    LockedPage node_page;
    ASSERT_EQ(fs.GetNodeManager().GetNodePage(nid, &node_page), ZX_OK);
    Node *node = node_page->GetAddress<Node>();
    fault_injection(node);
    node_page.SetDirty();
  }

  // Create the child from the faulty node page
  auto vnode_or = fs.GetVnode(nid);
  ASSERT_EQ(vnode_or.status_value(), expected_status);
  if (expected_status == ZX_OK) {
    vnode_or->Close();
  }
}

TEST_F(VnodeTest, Time) TA_NO_THREAD_SAFETY_ANALYSIS {
  std::string dir_name("test");
  zx::result test_fs_vnode = root_dir_->Create(dir_name, fs::CreationType::kDirectory);
  ASSERT_TRUE(test_fs_vnode.is_ok()) << test_fs_vnode.status_string();
  fbl::RefPtr<VnodeF2fs> test_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(*std::move(test_fs_vnode));

  ASSERT_EQ(test_vnode->GetNameView(), dir_name);

  timespec cur_time;
  clock_gettime(CLOCK_REALTIME, &cur_time);
  ASSERT_LE(zx::duration(test_vnode->GetTime<Timestamps::AccessTime>()), zx::duration(cur_time));
  ASSERT_LE(zx::duration(test_vnode->GetTime<Timestamps::ChangeTime>()), zx::duration(cur_time));
  ASSERT_LE(zx::duration(test_vnode->GetTime<Timestamps::ModificationTime>()),
            zx::duration(cur_time));

  ASSERT_EQ(test_vnode->Close(), ZX_OK);
  test_vnode = nullptr;
}

TEST_F(VnodeTest, Advise) TA_NO_THREAD_SAFETY_ANALYSIS {
  std::string dir_name("test");
  zx::result test_fs_vnode = root_dir_->Create(dir_name, fs::CreationType::kDirectory);
  ASSERT_TRUE(test_fs_vnode.is_ok()) << test_fs_vnode.status_string();
  fbl::RefPtr<VnodeF2fs> test_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(*std::move(test_fs_vnode));
  Dir *test_dir_ptr = static_cast<Dir *>(test_vnode.get());

  ASSERT_EQ(test_vnode->GetNameView(), dir_name);

  FileTester::CreateChild(test_dir_ptr, S_IFDIR, "f2fs_lower_case.avi");
  fbl::RefPtr<fs::Vnode> file_fs_vnode;
  FileTester::Lookup(test_dir_ptr, "f2fs_lower_case.avi", &file_fs_vnode);
  fbl::RefPtr<VnodeF2fs> file_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(std::move(file_fs_vnode));

  ASSERT_FALSE(file_vnode->IsAdviseSet(FAdvise::kCold));
  ASSERT_EQ(file_vnode->Close(), ZX_OK);

  FileTester::CreateChild(test_dir_ptr, S_IFDIR, "f2fs_upper_case.AVI");
  FileTester::Lookup(test_dir_ptr, "f2fs_upper_case.AVI", &file_fs_vnode);
  file_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(std::move(file_fs_vnode));

  ASSERT_FALSE(file_vnode->IsAdviseSet(FAdvise::kCold));

  file_vnode->SetColdFile();
  ASSERT_TRUE(file_vnode->IsAdviseSet(FAdvise::kCold));

  file_vnode->ClearAdvise(FAdvise::kCold);
  ASSERT_FALSE(file_vnode->IsAdviseSet(FAdvise::kCold));

  ASSERT_EQ(file_vnode->Close(), ZX_OK);
  file_vnode = nullptr;
  ASSERT_EQ(test_vnode->Close(), ZX_OK);
  test_vnode = nullptr;
}

TEST_F(VnodeTest, EmptyOverridenMethods) {
  char buf[kBlockSize];
  size_t out, end;
  zx::vmo vmo;
  ASSERT_EQ(root_dir_->Read(buf, 0, kBlockSize, &out), ZX_ERR_NOT_SUPPORTED);
  ASSERT_EQ(root_dir_->Write(buf, 0, kBlockSize, &out), ZX_ERR_NOT_SUPPORTED);
  ASSERT_EQ(root_dir_->Append(buf, kBlockSize, &end, &out), ZX_ERR_NOT_SUPPORTED);
  ASSERT_EQ(root_dir_->Truncate(0), ZX_ERR_NOT_SUPPORTED);
}

TEST_F(VnodeTest, Mode) {
  zx::result dir_fs_vnode = root_dir_->Create("test_dir", fs::CreationType::kDirectory);
  ASSERT_TRUE(dir_fs_vnode.is_ok()) << dir_fs_vnode.status_string();
  fbl::RefPtr<VnodeF2fs> dir_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(*std::move(dir_fs_vnode));

  ASSERT_TRUE(S_ISDIR(dir_vnode->GetMode()));
  ASSERT_EQ(dir_vnode->IsDir(), true);
  ASSERT_EQ(dir_vnode->IsReg(), false);
  ASSERT_EQ(dir_vnode->IsLink(), false);
  ASSERT_EQ(dir_vnode->IsChr(), false);
  ASSERT_EQ(dir_vnode->IsBlk(), false);
  ASSERT_EQ(dir_vnode->IsSock(), false);
  ASSERT_EQ(dir_vnode->IsFifo(), false);

  ASSERT_EQ(dir_vnode->Close(), ZX_OK);
  dir_vnode = nullptr;

  zx::result file_fs_vnode = root_dir_->Create("test_file", fs::CreationType::kFile);
  ASSERT_TRUE(file_fs_vnode.is_ok()) << file_fs_vnode.status_string();
  fbl::RefPtr<VnodeF2fs> file_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(*std::move(file_fs_vnode));

  ASSERT_TRUE(S_ISREG(file_vnode->GetMode()));
  ASSERT_EQ(file_vnode->IsDir(), false);
  ASSERT_EQ(file_vnode->IsReg(), true);
  ASSERT_EQ(file_vnode->IsLink(), false);
  ASSERT_EQ(file_vnode->IsChr(), false);
  ASSERT_EQ(file_vnode->IsBlk(), false);
  ASSERT_EQ(file_vnode->IsSock(), false);
  ASSERT_EQ(file_vnode->IsFifo(), false);

  ASSERT_EQ(file_vnode->Close(), ZX_OK);
  file_vnode = nullptr;
}

TEST_F(VnodeTest, WriteInode) {
  fbl::RefPtr<VnodeF2fs> test_vnode;
  // 1. Check node ino exception
  ASSERT_EQ(fs_->GetVnode(fs_->GetSuperblockInfo().GetNodeIno()).status_value(), ZX_ERR_NOT_FOUND);

  // 2. Check GetNodePage() exception
  FileTester::CreateChild(root_dir_.get(), S_IFDIR, "write_inode_dir");
  fbl::RefPtr<fs::Vnode> dir_raw_vnode;
  FileTester::Lookup(root_dir_.get(), "write_inode_dir", &dir_raw_vnode);
  test_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(std::move(dir_raw_vnode));

  // 3. Write inode
  ASSERT_TRUE(test_vnode->IsDirty());
  fs_->SyncFs();
  ASSERT_FALSE(test_vnode->IsDirty());

  ASSERT_EQ(test_vnode->Close(), ZX_OK);
  test_vnode = nullptr;
}

TEST_F(VnodeTest, GetVnodeExceptionCase) {
  DisableFsck();

  fbl::RefPtr<VnodeF2fs> test_vnode;
  NodeManager &node_manager = fs_->GetNodeManager();
  nid_t nid;

  // 1. Check GetVnode() GetNodePage() exception
  auto nid_or = node_manager.AllocNid();
  ASSERT_TRUE(nid_or.is_ok());
  nid = *nid_or;
  ASSERT_EQ(fs_->GetVnode(nid).status_value(), ZX_ERR_NOT_FOUND);

  // 2. Check GetVnode() GetNlink() exception
  auto nlink_fault_inject = [](Node *node) { node->i.i_links = 0; };
  VgetFaultInjetionAndTest(*fs_, *root_dir_, "nlink_dir", nlink_fault_inject, ZX_ERR_NOT_FOUND);
}

TEST_F(VnodeTest, SetAttributes) {
  zx::result dir_fs_vnode = root_dir_->Create("test_dir", fs::CreationType::kDirectory);
  ASSERT_TRUE(dir_fs_vnode.is_ok()) << dir_fs_vnode.status_string();
  fbl::RefPtr<VnodeF2fs> dir_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(*std::move(dir_fs_vnode));

  ASSERT_EQ(dir_vnode->UpdateAttributes({}), zx::ok());
  ASSERT_EQ(dir_vnode->UpdateAttributes(
                fs::VnodeAttributesUpdate{.creation_time = 1, .modification_time = 1}),
            zx::ok());

  ASSERT_EQ(dir_vnode->Close(), ZX_OK);
  dir_vnode = nullptr;
}

TEST_F(VnodeTest, TruncateExceptionCase) TA_NO_THREAD_SAFETY_ANALYSIS {
  zx::result file_fs_vnode = root_dir_->Create("test_file", fs::CreationType::kFile);
  ASSERT_TRUE(file_fs_vnode.is_ok()) << file_fs_vnode.status_string();
  fbl::RefPtr<VnodeF2fs> file_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(*std::move(file_fs_vnode));

  // 1. Check TruncateBlocks() exception
  file_vnode->SetSize(1);
  ASSERT_EQ(file_vnode->TruncateBlocks(1), ZX_OK);
  ASSERT_EQ(file_vnode->GetSize(), 1UL);

  const pgoff_t direct_index = 1;
  const pgoff_t direct_blks = kAddrsPerBlock;
  const pgoff_t indirect_blks = static_cast<const pgoff_t>(kAddrsPerBlock) * kNidsPerBlock;
  const pgoff_t indirect_index_lv1 = direct_index + kAddrsPerInode;
  const pgoff_t indirect_index_lv2 = indirect_index_lv1 + direct_blks * 2;
  const pgoff_t indirect_index_lv3 = indirect_index_lv2 + indirect_blks * 2;
  pgoff_t indirect_index_invalid_lv4 = indirect_index_lv3 + indirect_blks * kNidsPerBlock;
  uint32_t blocksize = fs_->GetSuperblockInfo().GetBlocksize();
  uint64_t invalid_size = indirect_index_invalid_lv4 * blocksize;

  file_vnode->SetSize(invalid_size);
  ASSERT_EQ(file_vnode->TruncateBlocks(invalid_size), ZX_ERR_NOT_FOUND);
  ASSERT_EQ(file_vnode->GetSize(), invalid_size);

  // 2. Check TruncateHole() exception
  file_vnode->SetSize(invalid_size);
  ASSERT_EQ(file_vnode->TruncateHole(invalid_size, invalid_size + 1), ZX_OK);
  ASSERT_EQ(file_vnode->GetSize(), invalid_size);

  ASSERT_EQ(file_vnode->Close(), ZX_OK);
  file_vnode = nullptr;
}

TEST_F(VnodeTest, SyncFile) {
  zx::result file_fs_vnode = root_dir_->Create("test_file", fs::CreationType::kFile);
  ASSERT_TRUE(file_fs_vnode.is_ok()) << file_fs_vnode.status_string();
  fbl::RefPtr<VnodeF2fs> file_vnode = fbl::RefPtr<VnodeF2fs>::Downcast(*std::move(file_fs_vnode));

  // For other fsync tests, see FsyncRecoveryTest.
  // 1. Check vnode is clean
  uint64_t pre_checkpoint_ver = fs_->GetSuperblockInfo().GetCheckpoint().checkpoint_ver;
  file_vnode->ClearDirty();
  ASSERT_EQ(file_vnode->SyncFile(false), ZX_OK);
  uint64_t curr_checkpoint_ver = fs_->GetSuperblockInfo().GetCheckpoint().checkpoint_ver;
  ASSERT_EQ(pre_checkpoint_ver, curr_checkpoint_ver);

  // 2. Check kNeedCp
  pre_checkpoint_ver = fs_->GetSuperblockInfo().GetCheckpoint().checkpoint_ver;
  file_vnode->SetFlag(InodeInfoFlag::kNeedCp);
  file_vnode->SetDirty();
  ASSERT_EQ(file_vnode->SyncFile(false), ZX_OK);
  ASSERT_FALSE(file_vnode->TestFlag(InodeInfoFlag::kNeedCp));
  curr_checkpoint_ver = fs_->GetSuperblockInfo().GetCheckpoint().checkpoint_ver;
  ASSERT_EQ(pre_checkpoint_ver + 1, curr_checkpoint_ver);

  // 3. Check SpaceForRollForward()
  pre_checkpoint_ver = fs_->GetSuperblockInfo().GetCheckpoint().checkpoint_ver;
  block_t temp_user_block_count = fs_->GetSuperblockInfo().GetTotalBlockCount();
  fs_->GetSuperblockInfo().SetTotalBlockCount(0);
  file_vnode->SetDirty();
  ASSERT_EQ(file_vnode->SyncFile(false), ZX_OK);
  ASSERT_FALSE(file_vnode->TestFlag(InodeInfoFlag::kNeedCp));
  curr_checkpoint_ver = fs_->GetSuperblockInfo().GetCheckpoint().checkpoint_ver;
  ASSERT_EQ(pre_checkpoint_ver + 1, curr_checkpoint_ver);
  fs_->GetSuperblockInfo().SetTotalBlockCount(temp_user_block_count);

  ASSERT_EQ(file_vnode->Close(), ZX_OK);
  file_vnode = nullptr;
}

TEST_F(VnodeTest, GetLockedDataPages) TA_NO_THREAD_SAFETY_ANALYSIS {
  zx::result file_fs_vnode = root_dir_->Create("test_dir", fs::CreationType::kDirectory);
  ASSERT_TRUE(file_fs_vnode.is_ok()) << file_fs_vnode.status_string();
  fbl::RefPtr<Dir> dir = fbl::RefPtr<Dir>::Downcast(*std::move(file_fs_vnode));

  constexpr pgoff_t kStartOffset = 1;
  constexpr pgoff_t kPageCount = 1000;
  constexpr pgoff_t kEndOffset = kStartOffset + kPageCount;
  constexpr pgoff_t kMidOffset = kEndOffset / 2;
  uint32_t page_count = kPageCount;
  constexpr uint32_t kPunchHoles = 10;

  // Get null block address
  {
    zx::result pages_or = dir->GetLockedDataPages(kStartOffset, kPageCount);
    ASSERT_TRUE(pages_or.is_ok());
    ASSERT_EQ(pages_or->size(), kPageCount);
    for (auto &page : *pages_or) {
      ASSERT_FALSE(page);
    }
  }

  // Make dirty pages
  {
    for (size_t i = kStartOffset; i < kEndOffset; ++i) {
      zx::result page = dir->GetNewLockedPage(i);
      ASSERT_TRUE(page.is_ok());
      page->SetDirty();
    }
  }

  // Cache hit case
  {
    zx::result pages_or = dir->GetLockedDataPages(kStartOffset, kPageCount);
    ASSERT_TRUE(pages_or.is_ok());
    ASSERT_EQ(pages_or->size(), page_count);
  }

  // Writeback dirty pages
  fs_->SyncFs();

  // Punch holes at middle
  dir->TruncateHole(kMidOffset, kMidOffset + kPunchHoles);

  // Test cache miss/hit cases
  for (size_t test = 0; test < 2; ++test) {
    zx::result pages_or = dir->GetLockedDataPages(kStartOffset, kPageCount);
    ASSERT_TRUE(pages_or.is_ok());
    ASSERT_EQ(pages_or->size(), page_count);
    auto page = pages_or->begin();
    for (size_t i = kStartOffset; i < kEndOffset; ++i, ++page) {
      if (i >= kMidOffset && i < kMidOffset + kPunchHoles) {
        ASSERT_FALSE(*page);
      } else {
        ASSERT_TRUE(*page);
        ASSERT_EQ((*page)->GetKey(), i);
      }
    }
    pages_or->clear();
    dir->GetFileCache().InvalidatePages(kMidOffset);
  }
  ASSERT_EQ(dir->Close(), ZX_OK);
}

}  // namespace
}  // namespace f2fs
