// Copyright 2016 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 <assert.h>
#include <lib/syslog/cpp/macros.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <iomanip>
#include <utility>

#include <fbl/alloc_checker.h>
#include <fbl/ref_ptr.h>
#include <storage/buffer/block_buffer.h>
#include <storage/operation/operation.h>

#include "src/storage/minfs/bcache.h"
#include "src/storage/minfs/format.h"
#include "src/storage/minfs/minfs_private.h"

namespace minfs {

zx_status_t Bcache::RunRequests(const std::vector<storage::BufferedOperation>& operations) {
  for (const storage::BufferedOperation& operation : operations) {
    if (operation.op.type != storage::OperationType::kWrite &&
        operation.op.type != storage::OperationType::kRead) {
      return ZX_ERR_NOT_SUPPORTED;
    }

    // TODO(fxbug.dev/47947): Clean up this hack.
    void* data = static_cast<uint8_t*>(operation.data) + operation.op.vmo_offset * kMinfsBlockSize;
    ssize_t result;
    if (operation.op.type == storage::OperationType::kRead) {
      result = pread(fd_.get(), data, operation.op.length * kMinfsBlockSize,
                     operation.op.dev_offset * kMinfsBlockSize);
    } else {
      result = pwrite(fd_.get(), data, operation.op.length * kMinfsBlockSize,
                      operation.op.dev_offset * kMinfsBlockSize);
    }

    if (result != static_cast<ssize_t>(operation.op.length * kMinfsBlockSize)) {
      // Linux and Mac don't agree on the number of "longs" on uint64_t.
      FX_LOGS(ERROR) << "RunOperation "
                     << (operation.op.type == storage::OperationType::kRead ? "read" : "write")
                     << " failure at block 0x" << std::hex << operation.op.dev_offset
                     << " result=" << std::dec << result;
      return ZX_ERR_IO;
    }
  }
  return ZX_OK;
}

zx_status_t Bcache::Readblk(blk_t bno, void* data) {
  off_t off = static_cast<off_t>(bno) * kMinfsBlockSize;
  assert(off / kMinfsBlockSize == bno);  // Overflow
  off += offset_;
  if (lseek(fd_.get(), off, SEEK_SET) < 0) {
    FX_LOGS(ERROR) << "cannot seek to block " << bno;
    return ZX_ERR_IO;
  }
  if (read(fd_.get(), data, kMinfsBlockSize) != kMinfsBlockSize) {
    FX_LOGS(ERROR) << "cannot read block " << bno;
    return ZX_ERR_IO;
  }
  return ZX_OK;
}

zx_status_t Bcache::Writeblk(blk_t bno, const void* data) {
  off_t off = static_cast<off_t>(bno) * kMinfsBlockSize;
  assert(off / kMinfsBlockSize == bno);  // Overflow
  off += offset_;
  if (lseek(fd_.get(), off, SEEK_SET) < 0) {
    FX_LOGS(ERROR) << "cannot seek to block " << bno << ". " << errno;
    return ZX_ERR_IO;
  }
  ssize_t ret = write(fd_.get(), data, kMinfsBlockSize);
  if (ret != kMinfsBlockSize) {
    FX_LOGS(ERROR) << "cannot write block " << bno << " (" << ret << ")";
    return ZX_ERR_IO;
  }
  return ZX_OK;
}

zx_status_t Bcache::Sync() {
  // No-op.
  return ZX_OK;
}

// Static.
zx_status_t Bcache::Create(fbl::unique_fd fd, uint32_t max_blocks, std::unique_ptr<Bcache>* out) {
  out->reset(new Bcache(std::move(fd), max_blocks));
  return ZX_OK;
}

Bcache::Bcache(fbl::unique_fd fd, uint32_t max_blocks)
    : fd_(std::move(fd)), max_blocks_(max_blocks) {}

zx_status_t Bcache::SetOffset(off_t offset) {
  if (offset_ || extent_lengths_.size() > 0) {
    return ZX_ERR_ALREADY_BOUND;
  }
  offset_ = offset;
  return ZX_OK;
}

zx_status_t Bcache::SetSparse(off_t offset, const fbl::Vector<size_t>& extent_lengths) {
  if (offset_ || extent_lengths_.size() > 0) {
    return ZX_ERR_ALREADY_BOUND;
  }

  ZX_ASSERT(extent_lengths.size() == kExtentCount);

  fbl::AllocChecker ac;
  extent_lengths_.reset(new (&ac) size_t[kExtentCount], kExtentCount);

  if (!ac.check()) {
    return ZX_ERR_NO_MEMORY;
  }

  for (size_t i = 0; i < extent_lengths.size(); i++) {
    extent_lengths_[i] = extent_lengths[i];
  }

  offset_ = offset;
  return ZX_OK;
}

}  // namespace minfs
