// 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_MINFS_LAZY_READER_H_
#define SRC_STORAGE_MINFS_LAZY_READER_H_

#include <lib/zx/status.h>

#include <memory>
#include <vector>

#include <bitmap/rle-bitmap.h>
#include <fbl/algorithm.h>
#include <fs/transaction/buffered_operations_builder.h>
#include <fs/transaction/transaction_handler.h>

#include "src/storage/minfs/block_utils.h"
#include "src/storage/minfs/format.h"
#include "src/storage/minfs/writeback.h"

namespace minfs {

// LazyReader helps with lazily reading blocks in a file.
class LazyReader {
 public:
  LazyReader() = default;

  LazyReader(const LazyReader&) = delete;
  LazyReader& operator=(const LazyReader&) = delete;

  // An interface for reading blocks. An instance is passed to the Read method.
  class ReaderInterface {
   public:
    ReaderInterface() = default;

    // Not copyable or movable.
    ReaderInterface(ReaderInterface&) = delete;
    ReaderInterface& operator=(ReaderInterface&) = delete;

    virtual ~ReaderInterface() = default;

    // Queue a read for |range| blocks. Returns the number of blocks enqueued. The remainder will be
    // pased to a subsequent call.
    [[nodiscard]] virtual zx::status<uint64_t> Enqueue(BlockRange range) = 0;

    // Issues the queued reads and returns the result.
    [[nodiscard]] virtual zx_status_t RunRequests() = 0;

    virtual uint32_t BlockSize() const = 0;
  };

  // Reads |length| bytes at offset |offset| into the buffer (if it isn't already pressent) using
  // the provided ReaderInterface. The actual reads will be blocks and so |range| will be aligned to
  // the nearest block boundaries that encompass |range|.
  [[nodiscard]] zx_status_t Read(ByteRange range, ReaderInterface* reader);

  // Marks the given block range as loaded or not according to |set|.
  void SetLoaded(BlockRange range, bool set);

 private:
  bitmap::RleBitmapBase<uint64_t> mapped_;
};

// An interface for mapping file blocks to device blocks.
class MapperInterface {
 public:
  MapperInterface() = default;

  // Not copyable or movable.
  MapperInterface(MapperInterface&) = delete;
  MapperInterface& operator=(MapperInterface&) = delete;

  virtual ~MapperInterface() = default;

  // Maps from file block to device block.
  [[nodiscard]] virtual zx::status<DeviceBlockRange> Map(BlockRange file_range) = 0;

  // Same as Map, but if |allocated| is non-null, blocks should be allocated if necessary and
  // |allocated| will be updated to indicate whether an allocation took place.
  [[nodiscard]] virtual zx::status<DeviceBlockRange> MapForWrite(PendingWork* transaction,
                                                                 BlockRange file_range,
                                                                 bool* allocated) = 0;
};

// MappedFileReader is a reader that can be used with LazyReader to read files that are mapped with
// an instance of MapperInterface.
class MappedFileReader : public LazyReader::ReaderInterface {
 public:
  MappedFileReader(fs::TransactionHandler* handler, MapperInterface* mapper,
                   storage::BlockBuffer* buffer)
      : handler_(*handler), mapper_(*mapper), buffer_(*buffer) {}

  uint32_t BlockSize() const override { return buffer_.BlockSize(); }

  zx::status<uint64_t> Enqueue(BlockRange range) override;

  [[nodiscard]] zx_status_t RunRequests() override {
    return handler_.RunRequests(builder_.TakeOperations());
  }

  MapperInterface& mapper() { return mapper_; }

 private:
  fs::TransactionHandler& handler_;
  MapperInterface& mapper_;
  storage::BlockBuffer& buffer_;
  fs::BufferedOperationsBuilder builder_;
};

}  // namespace minfs

#endif  // SRC_STORAGE_MINFS_LAZY_READER_H_
