// Copyright 2018 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 "allocator/extent-reserver.h"

#include <bitmap/rle-bitmap.h>
#include <gtest/gtest.h>

#include "allocator/node-reserver.h"

namespace blobfs {
namespace {

// Test simple cases of reserving a single extent
TEST(ExtentReserverTest, Reserve) {
  ExtentReserver reserver;
  BlockOffsetType start_block = 0;
  BlockCountType block_count = 1;
  Extent extent(start_block, block_count);

  // The ReservedExtent constructor should reserve the extent.
  // The destructor should release the extent.
  {
    ReservedExtent reserved_extent = reserver.Reserve(extent);
    EXPECT_EQ(block_count, reserver.ReservedBlockCount());
  }
  EXPECT_EQ(0u, reserver.ReservedBlockCount());
}

TEST(ExtentReserverTest, ReserveReset) {
  ExtentReserver reserver;
  BlockOffsetType start_block = 0;
  BlockCountType block_count = 1;
  Extent extent(start_block, block_count);

  // The ReservedExtent constructor should reserve the extent.
  // Reset should release the extent.
  {
    ReservedExtent reserved_extent = reserver.Reserve(extent);
    EXPECT_EQ(block_count, reserver.ReservedBlockCount());
    reserved_extent.Reset();
    EXPECT_EQ(0u, reserver.ReservedBlockCount());
  }
  EXPECT_EQ(0u, reserver.ReservedBlockCount());
}

// Test the constructors of the reserved extent.
TEST(ExtentReserverTest, Constructor) {
  ExtentReserver reserver;
  BlockOffsetType start_block = 0;
  BlockCountType block_count = 1;
  Extent extent(start_block, block_count);

  // Test reservation via the constructor.
  {
    ReservedExtent reserved_extent = reserver.Reserve(extent);
    EXPECT_EQ(extent.Start(), reserved_extent.extent().Start());
    EXPECT_EQ(extent.Length(), reserved_extent.extent().Length());
    EXPECT_EQ(block_count, reserver.ReservedBlockCount());
  }
  EXPECT_EQ(0u, reserver.ReservedBlockCount());
}

TEST(ExtentReserverTest, MoveConstructor) {
  ExtentReserver reserver;
  BlockOffsetType start_block = 0;
  BlockCountType block_count = 1;
  Extent extent(start_block, block_count);

  // Test reservation via move constructor.
  {
    ReservedExtent source_extent = reserver.Reserve(extent);
    EXPECT_EQ(1u, reserver.ReservedBlockCount());
    EXPECT_EQ(extent.Start(), source_extent.extent().Start());
    EXPECT_EQ(extent.Length(), source_extent.extent().Length());

    ReservedExtent dest_extent(std::move(source_extent));
    EXPECT_EQ(1u, reserver.ReservedBlockCount());
    EXPECT_EQ(extent.Start(), dest_extent.extent().Start());
    EXPECT_EQ(extent.Length(), dest_extent.extent().Length());
  }
  EXPECT_EQ(0u, reserver.ReservedBlockCount());
}

TEST(ExtentReserverTest, MoveAssignment) {
  ExtentReserver reserver;
  BlockOffsetType start_block = 0;
  BlockCountType block_count = 1;
  Extent extent(start_block, block_count);

  // Test reservation via the move assignment operator.
  {
    ReservedExtent source_extent = reserver.Reserve(extent);
    EXPECT_EQ(1u, reserver.ReservedBlockCount());
    EXPECT_EQ(extent.Start(), source_extent.extent().Start());
    EXPECT_EQ(extent.Length(), source_extent.extent().Length());

    ReservedExtent dest_extent = std::move(source_extent);
    EXPECT_EQ(1u, reserver.ReservedBlockCount());
    EXPECT_EQ(extent.Start(), dest_extent.extent().Start());
    EXPECT_EQ(extent.Length(), dest_extent.extent().Length());
  }
}

// Test splitting of extents.
TEST(ExtentReserverTest, Split) {
  ExtentReserver reserver;
  uint64_t start_block = 0;
  BlockCountType block_count = 10;
  Extent extent{start_block, block_count};

  EXPECT_EQ(0u, reserver.ReservedBlockCount());
  ReservedExtent reserved_extent = reserver.Reserve(extent);
  EXPECT_EQ(10u, reserver.ReservedBlockCount());

  {
    const BlockCountType split_point = 5;
    ReservedExtent latter(reserved_extent.SplitAt(split_point));
    // After splitting, no reservations actually change.
    EXPECT_EQ(10u, reserver.ReservedBlockCount());

    // Verify the split extents contain the expected values.
    EXPECT_EQ(extent.Start(), reserved_extent.extent().Start());
    EXPECT_EQ(split_point, reserved_extent.extent().Length());

    EXPECT_EQ(extent.Start() + split_point, latter.extent().Start());
    EXPECT_EQ(block_count - split_point, latter.extent().Length());
  }

  // When the latter half of the reservation goes out of scope, the reservations
  // are cleaned up too.
  EXPECT_EQ(5u, reserver.ReservedBlockCount());
}

}  // namespace
}  // namespace blobfs
