// 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/virtualization/bin/vmm/device/block_dispatcher.h"

#include <lib/syslog/cpp/macros.h>
#include <lib/trace/event.h>
#include <lib/zx/vmo.h>

#include <bitmap/rle-bitmap.h>

#include "src/virtualization/bin/vmm/device/block.h"
#include "src/virtualization/bin/vmm/device/qcow.h"

static_assert(fuchsia::io::MAX_BUF % kBlockSectorSize == 0,
              "Maximum buffer size is not a multiple of sector size");
static constexpr size_t kMaxBufSectors = fuchsia::io::MAX_BUF / kBlockSectorSize;

// Dispatcher that fulfills block requests using Fuchsia IO.
class RawBlockDispatcher : public BlockDispatcher {
 public:
  explicit RawBlockDispatcher(fuchsia::io::FilePtr file) : file_(std::move(file)) {}

 private:
  fuchsia::io::FilePtr file_;

  void Sync(Callback callback) override {
    TRACE_DURATION("machina", "RawBlockDispatcher::Sync");
    file_->Sync(std::move(callback));
  }

  void ReadAt(void* data, uint64_t size, uint64_t off, Callback callback) override {
    TRACE_DURATION("machina", "RawBlockDispatcher::ReadAt", "size", size, "off", off);
    auto io_guard = fbl::MakeRefCounted<IoGuard>(std::move(callback));
    auto addr = static_cast<uint8_t*>(data);
    for (uint64_t at = 0; at < size; at += fuchsia::io::MAX_BUF) {
      auto len = std::min<uint64_t>(size - at, fuchsia::io::MAX_BUF);
      auto read = [io_guard, len, begin = addr + at](zx_status_t status, std::vector<uint8_t> buf) {
        if (status != ZX_OK) {
          io_guard->SetStatus(status);
        } else if (buf.size() != len) {
          io_guard->SetStatus(ZX_ERR_IO);
        } else {
          memcpy(begin, buf.data(), buf.size());
        }
      };
      file_->ReadAt(len, off + at, read);
    }
  }

  void WriteAt(const void* data, uint64_t size, uint64_t off, Callback callback) override {
    TRACE_DURATION("machina", "RawBlockDispatcher::WriteAt", "size", size, "off", off);
    auto io_guard = fbl::MakeRefCounted<IoGuard>(std::move(callback));
    auto addr = static_cast<const uint8_t*>(data);
    for (uint64_t at = 0; at < size; at += fuchsia::io::MAX_BUF) {
      auto len = std::min<uint64_t>(size - at, fuchsia::io::MAX_BUF);
      auto write = [io_guard, len](zx_status_t status, uint64_t actual) {
        if (status != ZX_OK) {
          io_guard->SetStatus(status);
        } else if (actual != len) {
          io_guard->SetStatus(ZX_ERR_IO);
        }
      };
      auto begin = addr + at;
      std::vector<uint8_t> buf(begin, begin + len);
      // TODO(fxbug.dev/12536): Add support for channel back-pressure.
      file_->WriteAt(std::move(buf), off + at, write);
    }
  }
};

void CreateRawBlockDispatcher(fuchsia::io::FilePtr file, NestedBlockDispatcherCallback callback) {
  file->GetAttr([file = std::move(file), callback = std::move(callback)](
                    zx_status_t status, fuchsia::io::NodeAttributes attrs) mutable {
    FX_CHECK(status == ZX_OK) << "Failed to get attributes " << status;
    auto disp = std::make_unique<RawBlockDispatcher>(std::move(file));
    callback(attrs.content_size, std::move(disp));
  });
}

// Dispatcher that fulfills block requests using Fuchsia IO and a VMO.
class VmoBlockDispatcher : public BlockDispatcher {
 public:
  VmoBlockDispatcher(fuchsia::io::FilePtr file, zx::vmo vmo, size_t vmo_size, uintptr_t vmar_addr)
      : file_(std::move(file)), vmo_(std::move(vmo)), vmo_size_(vmo_size), vmar_addr_(vmar_addr) {}

 private:
  fuchsia::io::FilePtr file_;
  const zx::vmo vmo_;
  const size_t vmo_size_;
  const uintptr_t vmar_addr_;

  void Sync(Callback callback) override {
    TRACE_DURATION("machina", "VmoBlockDispatcher::Sync");
    file_->Sync(std::move(callback));
  }

  void ReadAt(void* data, uint64_t size, uint64_t off, Callback callback) override {
    TRACE_DURATION("machina", "VmoBlockDispatcher::ReadAt", "size", size, "off", off);
    if (size + off < size || size + off > vmo_size_) {
      callback(ZX_ERR_OUT_OF_RANGE);
      return;
    }
    memcpy(data, reinterpret_cast<const void*>(vmar_addr_ + off), size);
    callback(ZX_OK);
  }

  void WriteAt(const void* data, uint64_t size, uint64_t off, Callback callback) override {
    TRACE_DURATION("machina", "VmoBlockDispatcher::WriteAt", "size", size, "off", off);
    if (size + off < size || size + off > vmo_size_) {
      callback(ZX_ERR_OUT_OF_RANGE);
      return;
    }
    memcpy(reinterpret_cast<void*>(vmar_addr_ + off), data, size);
    callback(ZX_OK);
  }
};

void CreateVmoBlockDispatcher(fuchsia::io::FilePtr file, uint32_t vmo_flags,
                              NestedBlockDispatcherCallback callback) {
  file->GetBuffer(vmo_flags, [file = std::move(file), vmo_flags, callback = std::move(callback)](
                                 zx_status_t status, fuchsia::mem::BufferPtr buffer) mutable {
    // If the file is not backed by a vmo, or if we fail to get it, then fall back to a raw block
    // dispatcher.
    if (status != ZX_OK) {
      CreateRawBlockDispatcher(std::move(file), std::move(callback));
      return;
    }
    uintptr_t addr;
    status = zx::vmar::root_self()->map(vmo_flags, 0, buffer->vmo, 0, buffer->size, &addr);
    FX_CHECK(status == ZX_OK) << "Failed to map VMO " << status;
    auto disp = std::make_unique<VmoBlockDispatcher>(std::move(file), std::move(buffer->vmo),
                                                     buffer->size, addr);
    callback(buffer->size, std::move(disp));
  });
}

// Dispatcher that retains writes in-memory and delegates reads to another
// dispatcher.
class VolatileWriteBlockDispatcher : public BlockDispatcher {
 public:
  VolatileWriteBlockDispatcher(std::unique_ptr<BlockDispatcher> disp, zx::vmo vmo, size_t vmo_size,
                               uintptr_t vmar_addr)
      : disp_(std::move(disp)), vmo_(std::move(vmo)), vmo_size_(vmo_size), vmar_addr_(vmar_addr) {}

  ~VolatileWriteBlockDispatcher() override {
    zx_status_t status = zx::vmar::root_self()->unmap(vmar_addr_, vmo_size_);
    FX_DCHECK(status == ZX_OK);
  }

  void Sync(Callback callback) override {
    TRACE_DURATION("machina", "VolatileWriteBlockDispatcher::Sync");
    // Writes are synchronous, so sync is a no-op.
    callback(ZX_OK);
  }

  void ReadAt(void* data, uint64_t size, uint64_t off, Callback callback) override {
    TRACE_DURATION("machina", "VolatileWriteBlockDispatcher::ReadAt", "size", size, "off", off);
    if (!IsAccessValid(size, off)) {
      callback(ZX_ERR_INVALID_ARGS);
      return;
    }

    auto io_guard = fbl::MakeRefCounted<IoGuard>(std::move(callback));
    auto addr = static_cast<uint8_t*>(data);
    while (size > 0) {
      size_t sector = off / kBlockSectorSize;
      size_t num_sectors = size / kBlockSectorSize;
      size_t first_sector;
      bitmap_.Get(sector, sector + num_sectors, &first_sector);
      bool unallocated = first_sector == sector;
      if (unallocated) {
        // Not allocated, therefore calculate maximum unallocated read.
        num_sectors = std::min(kMaxBufSectors, num_sectors);
        bitmap_.Find(true, sector, sector + num_sectors, 1, &first_sector);
      }

      size_t read_size = (first_sector - sector) * kBlockSectorSize;
      if (unallocated) {
        // Not Allocated, delegate to dispatcher.
        auto callback = [io_guard](zx_status_t status) {
          if (status != ZX_OK) {
            io_guard->SetStatus(status);
          }
        };
        disp_->ReadAt(addr, read_size, off, callback);
      } else {
        // Region is at least partially cached.
        auto mapped_addr = reinterpret_cast<const void*>(vmar_addr_ + off);
        memcpy(addr, mapped_addr, read_size);
      }

      off += read_size;
      addr += read_size;
      FX_DCHECK(size >= read_size);
      size -= read_size;
    }
  }

  void WriteAt(const void* data, uint64_t size, uint64_t off, Callback callback) override {
    TRACE_DURATION("machina", "VolatileWriteBlockDispatcher::WriteAt", "size", size, "off", off);
    if (!IsAccessValid(size, off)) {
      callback(ZX_ERR_INVALID_ARGS);
      return;
    }

    size_t sector = off / kBlockSectorSize;
    size_t num_sectors = size / kBlockSectorSize;
    zx_status_t status = bitmap_.Set(sector, sector + num_sectors);
    if (status != ZX_OK) {
      callback(status);
      return;
    }

    auto mapped_addr = reinterpret_cast<void*>(vmar_addr_ + off);
    memcpy(mapped_addr, data, size);
    callback(ZX_OK);
  }

 private:
  std::unique_ptr<BlockDispatcher> disp_;
  zx::vmo vmo_;
  const size_t vmo_size_;
  const uintptr_t vmar_addr_;
  bitmap::RleBitmap bitmap_;

  bool IsAccessValid(uint64_t size, uint64_t off) {
    return size % kBlockSectorSize == 0 && off % kBlockSectorSize == 0 && off < vmo_size_ &&
           size <= vmo_size_ - off;
  }
};

void CreateVolatileWriteBlockDispatcher(size_t vmo_size, std::unique_ptr<BlockDispatcher> base,
                                        NestedBlockDispatcherCallback callback) {
  zx::vmo vmo;
  zx_status_t status = zx::vmo::create(vmo_size, 0, &vmo);
  FX_CHECK(status == ZX_OK) << "Failed to create VMO " << status;

  const char name[] = "volatile-block";
  status = vmo.set_property(ZX_PROP_NAME, name, sizeof(name));
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to set name of VMO " << status;
  }

  uintptr_t addr;
  status = zx::vmar::root_self()->map(
      ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_REQUIRE_NON_RESIZABLE, 0, vmo, 0, vmo_size, &addr);
  FX_CHECK(status == ZX_OK) << "Failed to map VMO " << status;

  auto disp = std::make_unique<VolatileWriteBlockDispatcher>(std::move(base), std::move(vmo),
                                                             vmo_size, addr);
  callback(vmo_size, std::move(disp));
}

// Dispatcher that reads from a QCOW image.
class QcowBlockDispatcher : public BlockDispatcher {
 public:
  QcowBlockDispatcher(std::unique_ptr<BlockDispatcher> disp, std::unique_ptr<QcowFile> file)
      : disp_(std::move(disp)), file_(std::move(file)) {}

 private:
  std::unique_ptr<BlockDispatcher> disp_;
  std::unique_ptr<QcowFile> file_;

  void Sync(Callback callback) override {
    // Writes are not supported, so sync is a no-op.
    TRACE_DURATION("machina", "QcowBlockDispatcher::Sync");
    callback(ZX_OK);
  }

  void ReadAt(void* data, uint64_t size, uint64_t off, Callback callback) override {
    TRACE_DURATION("machina", "QcowBlockDispatcher::ReadAt", "size", size, "off", off);
    file_->ReadAt(disp_.get(), data, size, off, std::move(callback));
  }

  void WriteAt(const void* data, uint64_t size, uint64_t off, Callback callback) override {
    TRACE_DURATION("machina", "QcowBlockDispatcher::WriteAt", "size", size, "off", off);
    callback(ZX_ERR_NOT_SUPPORTED);
  }
};

void CreateQcowBlockDispatcher(std::unique_ptr<BlockDispatcher> base,
                               NestedBlockDispatcherCallback callback) {
  auto base_ptr = base.get();
  auto file = std::make_unique<QcowFile>();
  auto file_ptr = file.get();
  auto load = [base = std::move(base), file = std::move(file),
               callback = std::move(callback)](zx_status_t status) mutable {
    size_t size = file->size();
    auto disp = std::make_unique<QcowBlockDispatcher>(std::move(base), std::move(file));
    callback(size, std::move(disp));
  };
  file_ptr->Load(base_ptr, std::move(load));
}
