// Copyright 2020 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 "external_memory_allocator.h"

#include <fidl/fuchsia.sysmem2/cpp/fidl.h>

#include <fbl/string_printf.h>

#include "macros.h"

namespace sysmem_driver {
ExternalMemoryAllocator::ExternalMemoryAllocator(
    MemoryAllocator::Owner* owner, fidl::WireSharedClient<fuchsia_hardware_sysmem::Heap> heap,
    fuchsia_hardware_sysmem::HeapProperties properties)
    : MemoryAllocator(properties), owner_(owner), heap_(std::move(heap)) {
  node_ = owner->heap_node()->CreateChild(
      fbl::StringPrintf("ExternalMemoryAllocator-%ld", id()).c_str());
  node_.CreateUint("id", id(), &properties_);
}

ExternalMemoryAllocator::~ExternalMemoryAllocator() { ZX_DEBUG_ASSERT(is_empty()); }

zx_status_t ExternalMemoryAllocator::Allocate(uint64_t size,
                                              const fuchsia_sysmem2::SingleBufferSettings& settings,
                                              std::optional<std::string> name,
                                              uint64_t buffer_collection_id, uint32_t buffer_index,
                                              zx::vmo* parent_vmo) {
  ZX_DEBUG_ASSERT_MSG(size % zx_system_get_page_size() == 0, "size: 0x%" PRIx64, size);
  ZX_DEBUG_ASSERT_MSG(
      fbl::round_up(*settings.buffer_settings()->size_bytes(), zx_system_get_page_size()) == size,
      "size_bytes: %" PRIu64 " size: 0x%" PRIx64, *settings.buffer_settings()->size_bytes(), size);
  // TODO(https://fxbug.dev/42135564): We're currently using WireSharedClient for the combination of "shared"
  // and sync() being available, but once we remove OnRegister we should also evaluate whether we
  // can just use fidl::SyncClient.
  fidl::Arena arena;
  auto allocate_result = heap_.sync()->AllocateVmo(size, fidl::ToWire(arena, settings),
                                                   buffer_collection_id, buffer_index);
  if (!allocate_result.ok() || !allocate_result->is_ok()) {
    DRIVER_ERROR("Heap.AllocateVmo failed: %d %d", allocate_result.error().status(),
                 allocate_result.ok() ? allocate_result->error_value() : ZX_ERR_INTERNAL);
    // sanitize to ZX_ERR_NO_MEMORY regardless of why.
    return ZX_ERR_NO_MEMORY;
  }
  zx::vmo result_vmo = std::move(allocate_result->value()->vmo);
  fbl::String vmo_name;
  if (name.has_value()) {
    vmo_name = fbl::StringPrintf("sysmem-ext %s", name.value().c_str());
  } else {
    vmo_name = "sysmem-ext";
  }
  result_vmo.set_property(ZX_PROP_NAME, vmo_name.c_str(), vmo_name.length());
  allocations_.try_emplace(result_vmo.get(), BufferKey{.buffer_collection_id = buffer_collection_id,
                                                       .buffer_index = buffer_index});
  *parent_vmo = std::move(result_vmo);
  return ZX_OK;
}

void ExternalMemoryAllocator::Delete(zx::vmo parent_vmo) {
  auto it = allocations_.find(parent_vmo.get());
  if (it == allocations_.end()) {
    DRIVER_ERROR("Invalid allocation - vmo_handle: %d", parent_vmo.get());
    return;
  }
  BufferKey buffer_key = it->second;
  allocations_.erase(it);
  auto result = heap_.sync()->DeleteVmo(buffer_key.buffer_collection_id, buffer_key.buffer_index,
                                        std::move(parent_vmo));
  if (!result.ok()) {
    DRIVER_ERROR("HeapDestroyResource() failed - status: %d", result.status());
    // fall-through; the server also pays attention to ZX_VMO_ZERO_CHILDREN; if the server still
    // exists/existed it'll find out that way
  }
  if (is_empty()) {
    owner_->CheckForUnbind();
  }
}

}  // namespace sysmem_driver
