// Copyright 2017 The Chromium 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 "base/memory/shared_memory.h"

#include <limits>

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

#include "base/bits.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/memory/shared_memory_tracker.h"
#include "base/process/process_metrics.h"
#include "starboard/types.h"

namespace base {

SharedMemory::SharedMemory() {}

SharedMemory::SharedMemory(const SharedMemoryHandle& handle, bool read_only)
    : shm_(handle), read_only_(read_only) {}

SharedMemory::~SharedMemory() {
  Unmap();
  Close();
}

// static
bool SharedMemory::IsHandleValid(const SharedMemoryHandle& handle) {
  return handle.IsValid();
}

// static
void SharedMemory::CloseHandle(const SharedMemoryHandle& handle) {
  DCHECK(handle.IsValid());
  handle.Close();
}

// static
size_t SharedMemory::GetHandleLimit() {
  // Duplicated from the internal Magenta kernel constant kMaxHandleCount
  // (kernel/lib/zircon/zircon.cpp).
  return 256 * 1024u;
}

bool SharedMemory::CreateAndMapAnonymous(size_t size) {
  return CreateAnonymous(size) && Map(size);
}

bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
  requested_size_ = options.size;
  mapped_size_ = bits::Align(requested_size_, GetPageSize());
  zx::vmo vmo;
  zx_status_t status = zx::vmo::create(mapped_size_, 0, &vmo);
  if (status != ZX_OK) {
    ZX_DLOG(ERROR, status) << "zx_vmo_create";
    return false;
  }

  if (!options.executable) {
    // If options.executable isn't set, drop that permission by replacement.
    const int kNoExecFlags = ZX_DEFAULT_VMO_RIGHTS & ~ZX_RIGHT_EXECUTE;
    status = vmo.replace(kNoExecFlags, &vmo);
    if (status != ZX_OK) {
      ZX_DLOG(ERROR, status) << "zx_handle_replace";
      return false;
    }
  }

  shm_ = SharedMemoryHandle(vmo.release(), mapped_size_,
                            UnguessableToken::Create());
  return true;
}

bool SharedMemory::MapAt(off_t offset, size_t bytes) {
  if (!shm_.IsValid())
    return false;

  if (bytes > static_cast<size_t>(std::numeric_limits<int>::max()))
    return false;

  if (memory_)
    return false;

  int flags = ZX_VM_FLAG_PERM_READ;
  if (!read_only_)
    flags |= ZX_VM_FLAG_PERM_WRITE;
  uintptr_t addr;
  zx_status_t status = zx::vmar::root_self()->map(
      0, *zx::unowned_vmo(shm_.GetHandle()), offset, bytes, flags, &addr);
  if (status != ZX_OK) {
    ZX_DLOG(ERROR, status) << "zx_vmar_map";
    return false;
  }
  memory_ = reinterpret_cast<void*>(addr);

  mapped_size_ = bytes;
  mapped_id_ = shm_.GetGUID();
  SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
  return true;
}

bool SharedMemory::Unmap() {
  if (!memory_)
    return false;

  SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);

  uintptr_t addr = reinterpret_cast<uintptr_t>(memory_);
  zx_status_t status = zx::vmar::root_self()->unmap(addr, mapped_size_);
  if (status != ZX_OK) {
    ZX_DLOG(ERROR, status) << "zx_vmar_unmap";
    return false;
  }

  memory_ = nullptr;
  mapped_id_ = UnguessableToken();
  return true;
}

void SharedMemory::Close() {
  if (shm_.IsValid()) {
    shm_.Close();
    shm_ = SharedMemoryHandle();
  }
}

SharedMemoryHandle SharedMemory::handle() const {
  return shm_;
}

SharedMemoryHandle SharedMemory::TakeHandle() {
  SharedMemoryHandle handle(shm_);
  handle.SetOwnershipPassesToIPC(true);
  Unmap();
  shm_ = SharedMemoryHandle();
  return handle;
}

SharedMemoryHandle SharedMemory::DuplicateHandle(
    const SharedMemoryHandle& handle) {
  return handle.Duplicate();
}

SharedMemoryHandle SharedMemory::GetReadOnlyHandle() const {
  zx::vmo duped_handle;
  const int kNoWriteOrExec =
      ZX_DEFAULT_VMO_RIGHTS &
      ~(ZX_RIGHT_WRITE | ZX_RIGHT_EXECUTE | ZX_RIGHT_SET_PROPERTY);
  zx_status_t status = zx::unowned_vmo(shm_.GetHandle())
                           ->duplicate(kNoWriteOrExec, &duped_handle);
  if (status != ZX_OK)
    return SharedMemoryHandle();

  SharedMemoryHandle handle(duped_handle.release(), shm_.GetSize(),
                            shm_.GetGUID());
  handle.SetOwnershipPassesToIPC(true);
  return handle;
}

}  // namespace base
