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

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

namespace minfs {

zx_status_t LazyReader::Read(ByteRange range, ReaderInterface* reader) {
  if (range.Length() == 0)
    return ZX_OK;

  // Find the first block that isn't loaded.
  const range::Range block_range = BytesToBlocks(range, reader->BlockSize());
  // TODO(fxbug.dev/50842): Make RleBitmap work with uint64_t.
  size_t block = static_cast<size_t>(block_range.Start());
  if (mapped_.GetOne(block)) {
    mapped_.Find(false, block + 1, block_range.End(), 1, &block);
  }

  // Loop through all unloaded block ranges and enqueue reads for them.
  while (block < block_range.End()) {
    size_t end;
    mapped_.Find(true, block + 1, block_range.End(), 1, &end);
    zx_status_t status = EnumerateBlocks(BlockRange(block, end),
                                         [&](BlockRange range) { return reader->Enqueue(range); });
    if (status != ZX_OK)
      return status;
    mapped_.Find(false, end + 1, block_range.End(), 1, &block);
  }

  // Issue and wait for the reads to complete.
  zx_status_t status = reader->RunRequests();
  if (status != ZX_OK)
    return status;

  // Mark the whole range as loaded.
  mapped_.Set(block_range.Start(), block_range.End());
  return ZX_OK;
}

void LazyReader::SetLoaded(BlockRange range, bool set) {
  if (set) {
    mapped_.Set(range.Start(), range.End());
  } else {
    mapped_.Clear(range.Start(), range.End());
  }
}

zx::status<uint64_t> MappedFileReader::Enqueue(BlockRange range) {
  zx::status<DeviceBlockRange> status = mapper_.Map(range);
  if (status.is_error())
    return status.take_error();
  const DeviceBlockRange device_range = status.value();
  if (device_range.IsMapped()) {
    builder_.Add(
        storage::Operation{
            .type = storage::OperationType::kRead,
            .vmo_offset = range.Start(),
            .dev_offset = device_range.block(),
            .length = device_range.count(),
        },
        &buffer_);
  } else {
    // This probably isn't necessary because the blocks should already be clean, but it's safe.
    buffer_.Zero(range.Start(), device_range.count());
  }
  return zx::ok(device_range.count());
}

}  // namespace minfs
