// Copyright 2018 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/blobfs/iterator/block_iterator.h"

#include <lib/syslog/cpp/macros.h>
#include <stdint.h>
#include <zircon/types.h>

#include <algorithm>

#include <safemath/safe_conversions.h>

#include "src/storage/blobfs/format.h"

namespace blobfs {

BlockIterator::BlockIterator(std::unique_ptr<ExtentIterator> iterator)
    : iterator_(std::move(iterator)) {}

bool BlockIterator::Done() const { return blocks_left_ == 0 && iterator_->Done(); }

uint64_t BlockIterator::BlockIndex() const { return iterator_->BlockIndex() - blocks_left_; }

zx_status_t BlockIterator::Next(uint64_t length, uint64_t* out_length, uint64_t* out_start) {
  ZX_DEBUG_ASSERT(!Done());

  // If there are no blocks left, refill the extent.
  if (!blocks_left_) {
    auto extent_or = iterator_->Next();
    if (extent_or.is_error()) {
      return extent_or.status_value();
    }
    extent_ = extent_or.value();
    blocks_left_ = extent_->Length();
  }

  // Return as many blocks as possible within this current extent.
  ZX_DEBUG_ASSERT(extent_ != nullptr);
  *out_length = std::min(blocks_left_, length);
  *out_start = (extent_->Start() + extent_->Length()) - blocks_left_;
  blocks_left_ -= *out_length;
  return ZX_OK;
}

zx_status_t IterateToBlock(BlockIterator* iter, uint64_t block_num) {
  while (!iter->Done() && block_num > iter->BlockIndex()) {
    uint64_t out_length = 0;
    uint64_t out_start = 0;
    uint64_t blocks_to_iterate_over = block_num - iter->BlockIndex();
    zx_status_t status = iter->Next(blocks_to_iterate_over, &out_length, &out_start);
    if (status != ZX_OK) {
      return status;
    }
  }
  if (iter->Done()) {
    return ZX_ERR_INVALID_ARGS;
  }
  return ZX_OK;
}

zx_status_t StreamBlocks(BlockIterator* iterator, uint64_t block_count, StreamFn stream) {
  while (block_count > 0) {
    if (iterator->Done()) {
      FX_LOGS(ERROR) << "Failed to access data (early exit)";
      return ZX_ERR_IO_DATA_INTEGRITY;
    }
    uint64_t local_offset = iterator->BlockIndex();
    uint64_t actual_length;
    uint64_t dev_offset;
    zx_status_t status = iterator->Next(block_count, &actual_length, &dev_offset);
    if (status != ZX_OK) {
      FX_LOGS(ERROR) << "Failed to iterate over blocks: " << status;
      return status;
    }
    status = stream(local_offset, dev_offset, actual_length);
    if (status != ZX_OK) {
      FX_LOGS(ERROR) << "Failed to enqueue blocks: " << status;
      return status;
    }
    block_count -= actual_length;
  }
  return ZX_OK;
}

}  // namespace blobfs
