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

#ifdef __Fuchsia__
#include <fidl/fuchsia.io/cpp/wire.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/trace/event.h>

#include <storage/buffer/vmo_buffer.h>
#include <storage/operation/operation.h>

#include "src/lib/storage/block_client/cpp/remote_block_device.h"
#endif  // __Fuchsia__

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <utility>

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

#include "src/storage/f2fs/f2fs.h"

namespace f2fs {

#ifdef __Fuchsia__
zx_status_t CreateBcache(std::unique_ptr<block_client::BlockDevice> device, bool* out_readonly,
                         std::unique_ptr<f2fs::Bcache>* out) {
  fuchsia_hardware_block_BlockInfo info;
  if (zx_status_t status = device->BlockGetInfo(&info); status != ZX_OK) {
    FX_LOGS(ERROR) << "Coult not access device info: " << status;
    return status;
  }

  uint64_t device_size = info.block_size * info.block_count;

  if (device_size == 0) {
    FX_LOGS(ERROR) << "Invalid device size";
    return ZX_ERR_NO_RESOURCES;
  }
  uint64_t block_count = device_size / kBlockSize;

  // The maximum volume size of f2fs is 16TB
  if (block_count >= std::numeric_limits<uint32_t>::max()) {
    FX_LOGS(ERROR) << "Block count overflow";
    return ZX_ERR_OUT_OF_RANGE;
  }

  return f2fs::Bcache::Create(std::move(device), block_count, kBlockSize, out);
}

std::unique_ptr<block_client::BlockDevice> Bcache::Destroy(std::unique_ptr<Bcache> bcache) {
  // Destroy the VmoBuffer before extracting the underlying device, as it needs
  // to de-register itself from the underlying block device to be terminated.
  bcache->DestroyVmoBuffer();
  return std::move(bcache->owned_device_);
}

Bcache::Bcache(block_client::BlockDevice* device, uint64_t max_blocks, block_t block_size)
    : max_blocks_(max_blocks), block_size_(block_size), device_(device) {}

zx_status_t Bcache::BlockAttachVmo(const zx::vmo& vmo, storage::Vmoid* out) {
  return GetDevice()->BlockAttachVmo(vmo, out);
}

zx_status_t Bcache::BlockDetachVmo(storage::Vmoid vmoid) {
  return GetDevice()->BlockDetachVmo(std::move(vmoid));
}

zx_status_t Bcache::Create(std::unique_ptr<block_client::BlockDevice> device, uint64_t max_blocks,
                           block_t block_size, std::unique_ptr<Bcache>* out) {
  zx_status_t status = Create(device.get(), max_blocks, block_size, out);
  if (status == ZX_OK) {
    (*out)->owned_device_ = std::move(device);
  }
  return status;
}

zx_status_t Bcache::Create(block_client::BlockDevice* device, uint64_t max_blocks,
                           block_t block_size, std::unique_ptr<Bcache>* out) {
  std::unique_ptr<Bcache> bcache(new Bcache(device, max_blocks, block_size));

  zx_status_t status = bcache->CreateVmoBuffer();
  if (status != ZX_OK) {
    return status;
  }

  status = bcache->VerifyDeviceInfo();
  if (status != ZX_OK) {
    return status;
  }

  *out = std::move(bcache);
  return ZX_OK;
}
#else   // __Fuchsia__
Bcache::Bcache(fbl::unique_fd fd, uint64_t max_blocks)
    : max_blocks_(max_blocks), fd_(std::move(fd)), buffer_(1, kBlockSize) {}

zx_status_t Bcache::Create(fbl::unique_fd fd, uint64_t max_blocks, std::unique_ptr<Bcache>* out) {
  uint64_t max_blocks_converted = max_blocks * kBlockSize / kDefaultSectorSize;
  std::unique_ptr<Bcache> bcache(new Bcache(std::move(fd), max_blocks_converted));
  *out = std::move(bcache);
  return ZX_OK;
}
#endif  // __Fuchsia__

zx_status_t Bcache::Readblk(block_t bno, void* data) {
  if (bno >= max_blocks_) {
    return ZX_ERR_OUT_OF_RANGE;
  }
#ifdef __Fuchsia__
  TRACE_DURATION("f2fs", "Bcache::Readblk", "blk", bno);
#endif
  storage::Operation operation = {};
  operation.type = storage::OperationType::kRead;
  operation.vmo_offset = 0;
  operation.dev_offset = bno;
  operation.length = 1;
  std::lock_guard lock(buffer_mutex_);
  zx_status_t status = RunOperation(operation, &buffer_);
  if (status != ZX_OK) {
    return status;
  }
  std::memcpy(data, buffer_.Data(0), BlockSize());
  return ZX_OK;
}

zx_status_t Bcache::Writeblk(block_t bno, const void* data) {
  if (bno >= max_blocks_) {
    return ZX_ERR_OUT_OF_RANGE;
  }
#ifdef __Fuchsia__
  TRACE_DURATION("f2fs", "Bcache::Writeblk", "blk", bno);
#endif
  storage::Operation operation = {};
  operation.type = storage::OperationType::kWrite;
  operation.vmo_offset = 0;
  operation.dev_offset = bno;
  operation.length = 1;
  std::lock_guard lock(buffer_mutex_);
  std::memcpy(buffer_.Data(0), data, BlockSize());
  return RunOperation(operation, &buffer_);
}

#ifdef __Fuchsia__
zx_status_t Bcache::RunRequests(const std::vector<storage::BufferedOperation>& operations) {
  std::shared_lock lock(mutex_);
  return DeviceTransactionHandler::RunRequests(operations);
}

zx_status_t Bcache::VerifyDeviceInfo() {
  zx_status_t status = device_->BlockGetInfo(&info_);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "cannot get block device information: " << status;
    return status;
  }

  if (BlockSize() % info_.block_size != 0) {
    FX_LOGS(WARNING) << "f2fs block size cannot be multiple of underlying block size: "
                     << info_.block_size;
    return ZX_ERR_BAD_STATE;
  }
  return ZX_OK;
}
#else   // __Fuchsia__
zx_status_t Bcache::RunOperation(const storage::Operation& operation,
                                 storage::BlockBuffer* buffer) {
  return TransactionHandler::RunOperation(operation, buffer);
}

zx_status_t Bcache::RunRequests(const std::vector<storage::BufferedOperation>& operations) {
  std::shared_lock lock(mutex_);
  for (auto& operation : operations) {
    const auto& op = operation.op;
    off_t off = static_cast<off_t>(op.dev_offset) * BlockSize();

    if (lseek(fd_.get(), off, SEEK_SET) < 0) {
      FX_LOGS(ERROR) << "seek failed at " << op.dev_offset << ". " << errno;
      return ZX_ERR_IO;
    }

    size_t length = op.length * BlockSize();
    size_t buffer_offset = op.vmo_offset * BlockSize();
    switch (op.type) {
      case storage::OperationType::kRead:
        if (size_t ret =
                read(fd_.get(), static_cast<uint8_t*>(operation.data) + buffer_offset, length);
            ret != length) {
          FX_LOGS(ERROR) << "read failed at " << op.dev_offset;
          return ZX_ERR_IO;
        }
        break;
      case storage::OperationType::kWrite:
        if (size_t ret =
                write(fd_.get(), static_cast<uint8_t*>(operation.data) + buffer_offset, length);
            ret != length) {
          FX_LOGS(ERROR) << "write failed at " << op.dev_offset << " (" << ret << ")";
          return ZX_ERR_IO;
        }
        break;
      case storage::OperationType::kTrim:
        // TODO : zeroing
        break;
      default:
        ZX_DEBUG_ASSERT_MSG(false, "Unsupported operation");
    }
  }
  return ZX_OK;
}
#endif  // __Fuchsia__

zx_status_t Bcache::Trim(block_t start, block_t num) {
#ifdef __Fuchsia__
  if (!(info_.flags & fuchsia_hardware_block_FLAG_TRIM_SUPPORT)) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  block_fifo_request_t request = {
      .opcode = BLOCKIO_TRIM,
      .vmoid = BLOCK_VMOID_INVALID,
      .length = static_cast<uint32_t>(BlockNumberToDevice(num)),
      .vmo_offset = 0,
      .dev_offset = BlockNumberToDevice(start),
  };

  return GetDevice()->FifoTransaction(&request, 1);
#else   // __Fuchsia__
  return ZX_OK;
#endif  // __Fuchsia__
}

}  // namespace f2fs
