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

// Tests minfs inspector behavior.

#include "src/storage/minfs/inspector/inspector.h"

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/sync/completion.h>

#include <disk_inspector/disk_inspector.h>
#include <fbl/string_printf.h>
#include <gtest/gtest.h>

#include "src/storage/lib/block_client/cpp/fake_block_device.h"
#include "src/storage/lib/vfs/cpp/journal/inspector_journal.h"
#include "src/storage/minfs/inspector/inspector_inode.h"
#include "src/storage/minfs/inspector/inspector_inode_table.h"
#include "src/storage/minfs/inspector/inspector_private.h"
#include "src/storage/minfs/inspector/inspector_superblock.h"
#include "src/storage/minfs/runner.h"

namespace minfs {
namespace {

using block_client::FakeBlockDevice;

constexpr uint64_t kBlockCount = 1 << 15;
constexpr uint32_t kBlockSize = 512;

// Mock InodeManager class to be used in inspector tests.
class MockInodeManager : public InspectableInodeManager {
 public:
  MockInodeManager() = default;
  MockInodeManager(const MockInodeManager&) = delete;
  MockInodeManager(MockInodeManager&&) = delete;
  MockInodeManager& operator=(const MockInodeManager&) = delete;
  MockInodeManager& operator=(MockInodeManager&&) = delete;

  void Load(ino_t inode_num, Inode* out) const final;
  bool CheckAllocated(uint32_t inode_num) const final;
  const Allocator* GetInodeAllocator() const final;
};

void MockInodeManager::Load(ino_t inode_num, Inode* out) const {}

// We fake that only the inode at index 1 is allocated.
bool MockInodeManager::CheckAllocated(uint32_t inode_num) const { return (inode_num == 1); }

const Allocator* MockInodeManager::GetInodeAllocator() const { return nullptr; }

uint64_t GetUint64Value(const disk_inspector::DiskObject* object) {
  size_t size;
  const void* buffer = nullptr;
  object->GetValue(&buffer, &size);

  if (size != sizeof(uint64_t)) {
    ADD_FAILURE() << "Unexpected value size";
    return 0;
  }
  return *reinterpret_cast<const uint64_t*>(buffer);
}

void RunSuperblockTest(SuperblockType version) {
  Superblock sb;
  sb.magic0 = kMinfsMagic0;
  sb.magic1 = kMinfsMagic1;
  sb.major_version = kMinfsCurrentMajorVersion;
  sb.flags = kMinfsFlagClean;
  sb.block_size = kMinfsBlockSize;
  sb.inode_size = kMinfsInodeSize;
  sb.oldest_minor_version = kMinfsCurrentMinorVersion;

  size_t size;
  const void* buffer = nullptr;

  auto superblock = std::make_unique<SuperBlockObject>(sb, version);
  switch (version) {
    case SuperblockType::kPrimary:
      ASSERT_EQ(superblock->GetName(), std::string_view(kSuperBlockName));
      break;
    case SuperblockType::kBackup:
      ASSERT_EQ(superblock->GetName(), std::string_view(kBackupSuperBlockName));
      break;
    default:
      FAIL() << "Unexpected superblock type";
  }
  ASSERT_EQ(kSuperblockNumElements, superblock->GetNumElements());

  std::unique_ptr<disk_inspector::DiskObject> obj0 = superblock->GetElementAt(0);
  obj0->GetValue(&buffer, &size);
  ASSERT_EQ(kMinfsMagic0, *(reinterpret_cast<const uint64_t*>(buffer)));

  std::unique_ptr<disk_inspector::DiskObject> obj1 = superblock->GetElementAt(1);
  obj1->GetValue(&buffer, &size);
  ASSERT_EQ(kMinfsMagic1, *(reinterpret_cast<const uint64_t*>(buffer)));

  std::unique_ptr<disk_inspector::DiskObject> obj2 = superblock->GetElementAt(2);
  obj2->GetValue(&buffer, &size);
  ASSERT_EQ(kMinfsCurrentMajorVersion, *(reinterpret_cast<const uint32_t*>(buffer)));

  std::unique_ptr<disk_inspector::DiskObject> obj4 = superblock->GetElementAt(3);
  obj4->GetValue(&buffer, &size);
  ASSERT_EQ(kMinfsFlagClean, *(reinterpret_cast<const uint32_t*>(buffer)));

  std::unique_ptr<disk_inspector::DiskObject> obj5 = superblock->GetElementAt(4);
  obj5->GetValue(&buffer, &size);
  ASSERT_EQ(kMinfsBlockSize, *(reinterpret_cast<const uint32_t*>(buffer)));

  std::unique_ptr<disk_inspector::DiskObject> obj6 = superblock->GetElementAt(5);
  obj6->GetValue(&buffer, &size);
  ASSERT_EQ(kMinfsInodeSize, *(reinterpret_cast<const uint32_t*>(buffer)));
}

TEST(InspectorTest, TestInodeTable) {
  auto inode_table_obj = std::unique_ptr<MockInodeManager>(new MockInodeManager());

  uint32_t allocated_num = 1;
  uint32_t inode_num = 3;
  std::unique_ptr<InodeTableObject> inode_mgr(
      new InodeTableObject(inode_table_obj.get(), allocated_num, inode_num));
  ASSERT_EQ(inode_mgr->GetName(), std::string_view(kInodeTableName));
  ASSERT_EQ(allocated_num, inode_mgr->GetNumElements());

  // The only allocated inode should be inode #1 as defined in |MockInodeManager::CheckAllocated|.
  std::unique_ptr<disk_inspector::DiskObject> obj0 = inode_mgr->GetElementAt(0);
  fbl::String name = fbl::StringPrintf("allocated #%d, inode #%d", 0, 1);
  ASSERT_EQ(obj0->GetName(), name);
  ASSERT_EQ(kInodeNumElements, obj0->GetNumElements());
}

TEST(InspectorTest, TestSuperblock) { RunSuperblockTest(SuperblockType::kPrimary); }

TEST(InspectorTest, TestInode) {
  Inode fileInode;
  fileInode.magic = kMinfsMagicFile;
  fileInode.size = 10;
  fileInode.block_count = 2;
  fileInode.link_count = 1;

  uint32_t allocated_num = 2;
  uint32_t inode_num = 4;
  std::unique_ptr<InodeObject> finodeObj(new InodeObject(allocated_num, inode_num, fileInode));
  fbl::String name = fbl::StringPrintf("allocated #%d, inode #%d", allocated_num, inode_num);
  ASSERT_EQ(finodeObj->GetName(), name);
  ASSERT_EQ(kInodeNumElements, finodeObj->GetNumElements());

  size_t size;
  const void* buffer = nullptr;

  std::unique_ptr<disk_inspector::DiskObject> obj0 = finodeObj->GetElementAt(0);
  obj0->GetValue(&buffer, &size);
  ASSERT_EQ(kMinfsMagicFile, *(reinterpret_cast<const uint32_t*>(buffer)));

  std::unique_ptr<disk_inspector::DiskObject> obj1 = finodeObj->GetElementAt(1);
  obj1->GetValue(&buffer, &size);
  ASSERT_EQ(*(reinterpret_cast<const uint32_t*>(buffer)), 10u);

  std::unique_ptr<disk_inspector::DiskObject> obj2 = finodeObj->GetElementAt(2);
  obj2->GetValue(&buffer, &size);
  ASSERT_EQ(*(reinterpret_cast<const uint32_t*>(buffer)), 2u);

  std::unique_ptr<disk_inspector::DiskObject> obj3 = finodeObj->GetElementAt(3);
  obj3->GetValue(&buffer, &size);
  ASSERT_EQ(*(reinterpret_cast<const uint32_t*>(buffer)), 1u);
}

TEST(InspectorTest, CorrectJournalLocation) {
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  auto device = std::make_unique<FakeBlockDevice>(kBlockCount, kBlockSize);

  // Format the device.
  auto bcache_or = Bcache::Create(std::move(device), kBlockCount);
  ASSERT_TRUE(Mkfs(bcache_or.value().get()).is_ok());

  MountOptions options = {};
  auto fs_or = minfs::Runner::Create(loop.dispatcher(), std::move(bcache_or.value()), options);
  ASSERT_TRUE(fs_or.is_ok());

  // Ensure the dirty bit is propagated to the device.
  sync_completion_t completion;
  fs_or->minfs().Sync([&completion](zx_status_t status) { sync_completion_signal(&completion); });
  ASSERT_EQ(sync_completion_wait(&completion, zx::duration::infinite().get()), ZX_OK);

  uint64_t journal_length = JournalBlocks(fs_or->minfs().Info());
  std::unique_ptr<RootObject> root_obj(new RootObject(std::move(fs_or.value())));

  // Root name
  ASSERT_EQ(root_obj->GetName(), std::string_view(kRootName));
  ASSERT_EQ(kRootNumElements, root_obj->GetNumElements());

  // Superblock.
  auto obj0 = root_obj->GetElementAt(0);
  ASSERT_EQ(obj0->GetName(), std::string_view(kSuperBlockName));
  ASSERT_EQ(kSuperblockNumElements, obj0->GetNumElements());

  // Inode Table.
  auto obj1 = root_obj->GetElementAt(1);
  ASSERT_EQ(obj1->GetName(), std::string_view(kInodeTableName));

  // Journal info.
  auto journalObj = root_obj->GetElementAt(2);
  EXPECT_EQ(journalObj->GetName(), std::string_view(fs::kJournalName));
  ASSERT_EQ(fs::kJournalNumElements, journalObj->GetNumElements());

  // Check if journal magic is correct.
  auto journalMagic = journalObj->GetElementAt(0);
  ASSERT_EQ(fs::kJournalMagic, GetUint64Value(journalMagic.get()));

  // Access journal entries.
  auto entries = journalObj->GetElementAt(5);
  EXPECT_EQ(entries->GetName(), std::string_view(fs::kJournalEntriesName));
  ASSERT_EQ(journal_length - fs::kJournalMetadataBlocks, entries->GetNumElements());

  // Parse the header block.
  //
  // Warning: This has tight coupling with the dirty bit and backup superblock.
  // To ensure this exists on the journal, we invoked sync earlier in the test.
  auto block = entries->GetElementAt(0);
  EXPECT_EQ(block->GetName(), std::string_view("Journal[0]: Header"));
  {
    auto entryMagic = block->GetElementAt(0);
    EXPECT_EQ(entryMagic->GetName(), std::string_view("magic"));
    ASSERT_EQ(fs::kJournalEntryMagic, GetUint64Value(entryMagic.get()));

    auto payload_blocks = block->GetElementAt(4);
    EXPECT_EQ(payload_blocks->GetName(), std::string_view("payload blocks"));
    ASSERT_EQ(GetUint64Value(payload_blocks.get()), 2ul);

    auto target_block = block->GetElementAt(5);
    EXPECT_EQ(target_block->GetName(), std::string_view("target block"));
    EXPECT_EQ(kSuperblockStart, GetUint64Value(target_block.get()));

    target_block = block->GetElementAt(6);
    EXPECT_EQ(target_block->GetName(), std::string_view("target block"));
    EXPECT_EQ(kNonFvmSuperblockBackup, GetUint64Value(target_block.get()));

    EXPECT_EQ(block->GetElementAt(7), nullptr);
  }

  // Parse the journal entries.
  block = entries->GetElementAt(1);
  EXPECT_EQ(block->GetName(), std::string_view("Journal[1]: Block"));

  block = entries->GetElementAt(2);
  EXPECT_EQ(block->GetName(), std::string_view("Journal[2]: Block"));

  // Parse the commit block.
  block = entries->GetElementAt(3);
  EXPECT_EQ(block->GetName(), std::string_view("Journal[3]: Commit"));
}

// Currently, the only difference between this test and TestSuperblock is that
// this returns a different name.
TEST(InspectorTest, TestBackupSuperblock) { RunSuperblockTest(SuperblockType::kBackup); }

}  // namespace
}  // namespace minfs
