// Copyright 2020 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 SRC_STORAGE_BLOBFS_INCLUDE_BLOBFS_BLOBFS_INSPECTOR_H_
#define SRC_STORAGE_BLOBFS_INCLUDE_BLOBFS_BLOBFS_INSPECTOR_H_

#include <lib/zx/status.h>

#include <string>
#include <vector>

#include "src/storage/blobfs/format.h"
#include <disk_inspector/buffer_factory.h>
#include <disk_inspector/common_types.h>
#include <disk_inspector/loader.h>
#include <fs/journal/format.h>
#include <fs/transaction/transaction_handler.h>

namespace blobfs {

// Bare-bone blobfs inspector that loads metadata from the backing block device and provides
// functions to return parsed structs.
class BlobfsInspector {
 public:
  // Creates a MinfsInspector from a block device. Tries to load the superblock from disk upon
  // creation by calling ReloadSuperblock().
  static zx::status<std::unique_ptr<BlobfsInspector>> Create(
      std::unique_ptr<fs::TransactionHandler> handler,
      std::unique_ptr<disk_inspector::BufferFactory> factory);

  // For functions which allow passing in a block buffer to either read/write data, users need to
  // make sure that the buffer is compatible with the inspector's |handler_|. We expose the buffer
  // factory here for users to grab buffers that work with the handler if they cannot create
  // compatible buffers themselves.
  const disk_inspector::BufferFactory* GetBufferFactory() const { return buffer_factory_.get(); }

  // This function is used to initialize minfs metadata buffers and to load the relavent data.
  zx_status_t Initialize();

  // Initializes the |superblock_| buffer and tries to load the superblock from disk into the
  // buffer. The MinfsInspector should be considered invalid and should not be used if this function
  // fails as either VmoBuffers cannot be created or we cannot read even the first block from the
  // underlying block device.
  zx_status_t ReloadSuperblock();

  // Initializes the |inode_bitmap_|, |inode_table_|, and |journal_| buffers based on |superblock_|
  // and tries to load the associated structs from disk into these buffers. Note: we do not consider
  // the failure of initializing and loading of any of these buffers to be errors to crash the
  // program as the class should still work to a reasonable degree in the case of debugging a
  // superblock with corruptions. For cases of failure, these bufffers have undefined size and data
  // inside. It is up to users to make sure that they make valid calls using other functions in this
  // class.
  void ReloadMetadataFromSuperblock();

  // Returns a copy of |superblock_|.
  Superblock InspectSuperblock();

  // Returns the number of inodes from |superblock_|.
  uint64_t GetInodeCount();

  // Returns the number of journal entires calculated from |superblock_|.
  uint64_t GetJournalEntryCount();

  // The following functions need to load data from disk, leading to the possibility of failed
  // loads. Since they need to return values, we have fit::results for all of the return types. In
  // addition, they all depend on the loaded |superblock_| value to get where to start indexing.

  // Loads the inode table blocks for which the inodes from |start_index| inclusive to |end_index|
  // exclusive from disk and returns the Inodes in the range as a vector.
  zx::status<std::vector<Inode>> InspectInodeRange(uint64_t start_index, uint64_t end_index);

  // Loads the first journal block
  zx::status<fs::JournalInfo> InspectJournalSuperblock();

  // Loads the |index| element journal entry block and returns it as a struct of type T. Only
  // supports casting to fs::JournalPrefix, fs::JournalHeaderBlock, and fs::JournalCommitBlock.
  template <typename T>
  zx::status<T> InspectJournalEntryAs(uint64_t index);

  // Loads the data bitmap blocks where the allocation bits for data blocks from |start_index|
  // inclusive to |end_index| exclusive are located from disk and returns the indices for which the
  // corresponding bits are allocated.
  zx::status<std::vector<uint64_t>> InspectDataBlockAllocatedInRange(uint64_t start_index,
                                                                     uint64_t end_index);

  // Writes the |superblock| argument to disk and sets |superblock_| to |superblock| if the write
  // succeeds.
  zx::status<> WriteSuperblock(Superblock superblock);

  // Writes the vector of |inodes| to disk as the range of inodes starting at |start_index| based on
  // |superblock_| specified location. If users wish to write ExtentContainers, we expect them to
  // treat the containers as Inodes and use this function to write them.
  zx::status<> WriteInodes(std::vector<Inode> inodes, uint64_t start_index);

  // Writes the |journal_info| as the journal superblock based on |superblock_| specified location.
  zx::status<> WriteJournalSuperblock(fs::JournalInfo journal_info);

  // Treats the entire |buffer| as journal entry blocks and writes the entire buffer to disk
  // starting at the |start_index| journal entry block.
  zx::status<> WriteJournalEntryBlocks(storage::BlockBuffer* buffer, uint64_t start_index);

  // Sets the block allocation bitmap bits starting from |start_index| inclusive to |end_index|
  // exclusive to |value| based on |superblock_| specified location.
  zx::status<> WriteDataBlockAllocationBits(bool value, uint64_t start_index, uint64_t end_index);

  // Writes the entire |buffer| to the data segment of disk starting at |start_index| data block
  // based on |superblock_| specified location.
  zx::status<> WriteDataBlocks(storage::BlockBuffer* buffer, uint64_t start_index);

 private:
  explicit BlobfsInspector(std::unique_ptr<fs::TransactionHandler> handler,
                           std::unique_ptr<disk_inspector::BufferFactory> buffer_factory);

  zx_status_t LoadNodeElement(storage::BlockBuffer* buffer, uint64_t index);
  zx_status_t LoadJournalEntry(storage::BlockBuffer* buffer, uint64_t index);

  std::unique_ptr<fs::TransactionHandler> handler_;
  std::unique_ptr<disk_inspector::BufferFactory> buffer_factory_;
  disk_inspector::Loader loader_;
  Superblock superblock_ = {};
  // Scratch buffer initialized to be a single block in the Create method.  Functions that use this
  // buffer should try to treat it as an initialized buffer only valid for the duration of the
  // function without any presaved state or ability for the function to save state.
  std::unique_ptr<storage::BlockBuffer> buffer_;
};

}  // namespace blobfs

#endif  // SRC_STORAGE_BLOBFS_INCLUDE_BLOBFS_BLOBFS_INSPECTOR_H_
