// Copyright 2017 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 "peridot/bin/ledger/storage/impl/object_impl.h"

#include <utility>

#include "peridot/bin/ledger/storage/impl/object_digest.h"

namespace storage {

namespace {
uint64_t ToFullPages(uint64_t value) {
  return (value + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));
}
}  // namespace

InlinedObject::InlinedObject(ObjectIdentifier identifier)
    : identifier_(std::move(identifier)) {}
InlinedObject::~InlinedObject() {}

ObjectIdentifier InlinedObject::GetIdentifier() const { return identifier_; }

Status InlinedObject::GetData(fxl::StringView* data) const {
  *data = ExtractObjectDigestData(identifier_.object_digest());
  return Status::OK;
}

StringObject::StringObject(ObjectIdentifier identifier, std::string content)
    : identifier_(std::move(identifier)), content_(std::move(content)) {}

StringObject::~StringObject() {}

ObjectIdentifier StringObject::GetIdentifier() const { return identifier_; }

Status StringObject::GetData(fxl::StringView* data) const {
  *data = content_;
  return Status::OK;
}

LevelDBObject::LevelDBObject(ObjectIdentifier identifier,
                             std::unique_ptr<leveldb::Iterator> iterator)
    : identifier_(std::move(identifier)), iterator_(std::move(iterator)) {}

LevelDBObject::~LevelDBObject() {}

ObjectIdentifier LevelDBObject::GetIdentifier() const { return identifier_; }

Status LevelDBObject::GetData(fxl::StringView* data) const {
  *data = convert::ExtendedStringView(iterator_->value());
  return Status::OK;
}

VmoObject::VmoObject(ObjectIdentifier identifier, fsl::SizedVmo vmo)
    : identifier_(std::move(identifier)), vmo_(std::move(vmo)) {}

VmoObject::~VmoObject() {
  if (vmar_) {
    vmar_.destroy();
  }
}

ObjectIdentifier VmoObject::GetIdentifier() const { return identifier_; }

Status VmoObject::GetData(fxl::StringView* data) const {
  Status status = Initialize();
  if (status != Status::OK) {
    return status;
  }
  *data = data_;
  return Status::OK;
}

Status VmoObject::GetVmo(fsl::SizedVmo* vmo) const {
  Status status = Initialize();
  if (status != Status::OK) {
    return status;
  }

  zx_status_t zx_status =
      vmo_.Duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_READ | ZX_RIGHT_MAP, vmo);
  if (zx_status != ZX_OK) {
    FXL_LOG(ERROR) << "Unable to duplicate a vmo. Status: " << zx_status;
    return Status::INTERNAL_IO_ERROR;
  }
  return Status::OK;
}

Status VmoObject::Initialize() const {
  if (initialized_) {
    return Status::OK;
  }

  uintptr_t allocate_address;
  zx_status_t zx_status = zx::vmar::root_self()->allocate(
      0, ToFullPages(vmo_.size()),
      ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC, &vmar_,
      &allocate_address);
  if (zx_status != ZX_OK) {
    FXL_LOG(ERROR) << "Unable to allocate VMAR. Error: " << zx_status;
    return Status::INTERNAL_IO_ERROR;
  }

  char* mapped_address;
  zx_status = vmar_.map(0, vmo_.vmo(), 0, vmo_.size(),
                        ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC,
                        reinterpret_cast<uintptr_t*>(&mapped_address));
  if (zx_status != ZX_OK) {
    FXL_LOG(ERROR) << "Unable to map VMO. Error: " << zx_status;
    vmar_.reset();
    return Status::INTERNAL_IO_ERROR;
  }

  data_ = fxl::StringView(mapped_address, vmo_.size());
  initialized_ = true;

  return Status::OK;
}

}  // namespace storage
