// 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 "lib/media/transport/mapped_shared_buffer.h"

#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>

#include "lib/fxl/logging.h"
#include "lib/media/transport/fifo_allocator.h"

namespace media {
namespace {

constexpr uint64_t kMaxBufferLen = 0x3fffffffffffffff;

}  // namespace

MappedSharedBuffer::MappedSharedBuffer() {}

MappedSharedBuffer::~MappedSharedBuffer() { Reset(); }

zx_status_t MappedSharedBuffer::InitNew(uint64_t size, uint32_t map_flags) {
  FXL_DCHECK(size > 0);

  zx::vmo vmo;

  zx_status_t status = zx::vmo::create(size, 0, &vmo);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "zx::vmo::create failed, status " << status;
    return status;
  }

  // Allocate physical memory for the buffer.
  status = vmo.op_range(ZX_VMO_OP_COMMIT, 0u, size, nullptr, 0u);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "zx::vmo::op_range failed, status " << status;
    return status;
  }

  return InitInternal(std::move(vmo), map_flags);
}

zx_status_t MappedSharedBuffer::InitFromVmo(zx::vmo vmo, uint32_t map_flags) {
  return InitInternal(std::move(vmo), map_flags);
}

zx_status_t MappedSharedBuffer::InitInternal(zx::vmo vmo, uint32_t map_flags) {
  Reset();

  uint64_t size;
  zx_status_t status = vmo.get_size(&size);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "zx::vmo::get_size failed, status " << status;
    return status;
  }

  if (size == 0 || size > kMaxBufferLen) {
    FXL_LOG(ERROR) << "zx::vmo::get_size returned invalid size " << size;
    return ZX_ERR_OUT_OF_RANGE;
  }

  size_ = size;

  // TODO(dalesat): Map only for required operations (read or write).
  uintptr_t mapped_buffer = 0u;
  status =
      zx::vmar::root_self()->map(0, vmo, 0u, size, map_flags, &mapped_buffer);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "zx::vmar::map failed, status " << status;
    return status;
  }

  buffer_ptr_ = reinterpret_cast<uint8_t*>(mapped_buffer);

  vmo_ = std::move(vmo);

  OnInit();

  return ZX_OK;
}

bool MappedSharedBuffer::initialized() const { return buffer_ptr_ != nullptr; }

void MappedSharedBuffer::Reset() {
  if (buffer_ptr_ != nullptr) {
    FXL_DCHECK(size_ != 0);
    zx_status_t status = zx::vmar::root_self()->unmap(
        reinterpret_cast<uintptr_t>(buffer_ptr_), size_);
    FXL_CHECK(status == ZX_OK);
    buffer_ptr_ = nullptr;
  }

  size_ = 0;
  vmo_.reset();
}

uint64_t MappedSharedBuffer::size() const { return size_; }

zx::vmo MappedSharedBuffer::GetDuplicateVmo(zx_rights_t rights) const {
  FXL_DCHECK(initialized());
  zx::vmo vmo;
  zx_status_t status = vmo_.duplicate(rights, &vmo);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "zx::handle::duplicate failed, status " << status;
  }

  return vmo;
}

bool MappedSharedBuffer::Validate(uint64_t offset, uint64_t size) {
  FXL_DCHECK(buffer_ptr_ != nullptr);
  return offset < size_ && size <= size_ - offset;
}

void* MappedSharedBuffer::PtrFromOffset(uint64_t offset) const {
  FXL_DCHECK(buffer_ptr_ != nullptr);

  if (offset == FifoAllocator::kNullOffset) {
    return nullptr;
  }

  FXL_DCHECK(offset < size_);
  return buffer_ptr_ + offset;
}

uint64_t MappedSharedBuffer::OffsetFromPtr(void* ptr) const {
  FXL_DCHECK(buffer_ptr_ != nullptr);
  if (ptr == nullptr) {
    return FifoAllocator::kNullOffset;
  }
  uint64_t offset = reinterpret_cast<uint8_t*>(ptr) - buffer_ptr_;
  FXL_DCHECK(offset < size_);
  return offset;
}

void MappedSharedBuffer::OnInit() {}

}  // namespace media
