// 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 <lib/fidl/llcpp/arena.h>

#include <iostream>

namespace fidl {

ArenaBase::~ArenaBase() { Clean(); }

void ArenaBase::Clean() {
  // Call all the destructors (starting with the last allocated object).
  // Because we only work with views, the destructors only close handles.
  while (last_destructor_ != nullptr) {
    last_destructor_->destructor(
        reinterpret_cast<uint8_t*>(last_destructor_) + FIDL_ALIGN(sizeof(Destructor)),
        last_destructor_->count);
    last_destructor_ = last_destructor_->next;
  }
  // Deletes all the extra blocks.
  while (last_extra_block_ != nullptr) {
    ExtraBlock* to_be_deleted = last_extra_block_;
    last_extra_block_ = last_extra_block_->next_block();
    delete[] reinterpret_cast<char*>(to_be_deleted);
  }
}

uint8_t* ArenaBase::Allocate(size_t size, size_t count,
                             void (*destructor_function)(uint8_t*, size_t)) {
  // Total size needed for the allocation (the header used for the deallocation and the data).
  size_t block_size = FIDL_ALIGN(size * count);
  // Checks that the multiplication didn't overflow.
  ZX_DEBUG_ASSERT((count == 0) || (block_size >= size));
  if (destructor_function != nullptr) {
    block_size += FIDL_ALIGN(sizeof(Destructor));
  }
  if (available_size_ < block_size) {
    // The data doesn't fit within the current block => allocate a new block.
    // Note: the data available at the end of the current block is lost forever (until the
    // deallocation of the arena).
    available_size_ =
        (block_size > ExtraBlock::kDefaultExtraSize) ? block_size : ExtraBlock::kDefaultExtraSize;
    size_t extra_block_size = available_size_ + FIDL_ALIGN(ExtraBlock::kExtraBlockHeaderSize);
    last_extra_block_ =
        new (new uint8_t[extra_block_size]) ExtraBlock(last_extra_block_, available_size_);
    next_data_available_ = last_extra_block_->data();
  }
  // At this point we have enough space within the current block (either because there was enough
  // space within the existing block or because we allocate a new block).
  uint8_t* data = next_data_available_;
  next_data_available_ += block_size;
  available_size_ -= block_size;
  if (destructor_function != nullptr) {
    // Creates the data used to deallocate this allocation.
    last_destructor_ = new (data) Destructor(last_destructor_, count, destructor_function);
    return data + FIDL_ALIGN(sizeof(Destructor));
  }
  return data;
}

AnyMemoryResource MakeFidlAnyMemoryResource(AnyArena& arena) {
  class ArenaMemoryResource : public MemoryResource {
   public:
    explicit ArenaMemoryResource(AnyArena& arena) : arena_(&arena) {}

    uint8_t* Allocate(uint32_t num_bytes) final {
      return arena_->AllocateVector<uint8_t>(num_bytes);
    }

   private:
    AnyArena* arena_;
  };
  return AnyMemoryResource(std::in_place_type_t<ArenaMemoryResource>{}, arena);
}

}  // namespace fidl
