// Copyright 2019 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 "src/storage/minfs/allocator/allocator_reservation.h"

#include <stdlib.h>

#include <utility>

#include "src/storage/minfs/allocator/allocator.h"

namespace minfs {

AllocatorReservation::AllocatorReservation(Allocator* allocator) : allocator_(*allocator) {}
AllocatorReservation::~AllocatorReservation() { Cancel(); }

zx::result<> AllocatorReservation::Reserve(PendingWork* transaction, size_t reserved) {
  if (reserved_ != 0) {
    return zx::error(ZX_ERR_BAD_STATE);
  }
  auto status = allocator_.Reserve({}, transaction, reserved);
  if (status.is_ok()) {
    reserved_ = reserved;
  }
  return status;
}

zx::result<> AllocatorReservation::ExtendReservation(PendingWork* transaction, size_t reserved) {
  auto status = allocator_.Reserve({}, transaction, reserved);
  if (status.is_ok()) {
    reserved_ += reserved;
  }
  return status;
}

size_t AllocatorReservation::Allocate() {
  ZX_ASSERT(reserved_ > 0);
  reserved_--;
  return allocator_.Allocate({}, this);
}

void AllocatorReservation::Deallocate(size_t element) { allocator_.Free(this, element); }

#ifdef __Fuchsia__
size_t AllocatorReservation::Swap(size_t old_index) {
  if (old_index > 0) {
    allocator_.Free(this, old_index);
  }
  return Allocate();
}

#endif

void AllocatorReservation::Cancel() {
  if (reserved_ > 0) {
    allocator_.Unreserve({}, reserved_);
    reserved_ = 0;
  }
}

PendingAllocations& AllocatorReservation::GetPendingAllocations(Allocator* allocator) {
  if (!allocations_) {
    allocations_ = std::make_unique<PendingAllocations>(allocator);
  }
  return *allocations_;
}

PendingDeallocations& AllocatorReservation::GetPendingDeallocations(Allocator* allocator) {
  if (!deallocations_) {
    deallocations_ = std::make_unique<PendingDeallocations>(allocator);
  }
  return *deallocations_;
}

void AllocatorReservation::Commit(PendingWork* transaction) {
  allocator_.Commit(transaction, this);
}

}  // namespace minfs
