// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google Inc.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//
// This file defines tests for the internal StringBlock class

#include "google/protobuf/string_block.h"

#include <cstddef>
#include <memory>
#include <string>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

// Must be included last
#include "google/protobuf/port_def.inc"

using ::testing::Eq;
using ::testing::Ne;

namespace google {
namespace protobuf {
namespace internal {
namespace {

size_t EffectiveSizeFor(int size) {
  size -= sizeof(StringBlock);
  return static_cast<size_t>(size - (size % sizeof(std::string)));
}

size_t AllocatedSizeFor(int size) {
  return EffectiveSizeFor(size) + sizeof(StringBlock);
}

TEST(StringBlockTest, HeapAllocateOneBlock) {
  StringBlock* block = StringBlock::New(nullptr);

  ASSERT_THAT(block, Ne(nullptr));
  EXPECT_THAT(block->next(), Eq(nullptr));
  ASSERT_TRUE(block->heap_allocated());
  EXPECT_THAT(block->allocated_size(), Eq(AllocatedSizeFor(256)));
  EXPECT_THAT(block->effective_size(), Eq(EffectiveSizeFor(256)));
  EXPECT_THAT(block->begin(), Eq(block->AtOffset(0)));
  EXPECT_THAT(block->end(), Eq(block->AtOffset(block->effective_size())));

  EXPECT_THAT(StringBlock::Delete(block), Eq(AllocatedSizeFor(256)));
}

TEST(StringBlockTest, EmplaceOneBlock) {
  // NextSize() returns unrounded 'min_size()' on first call.
  size_t size = StringBlock::NextSize(nullptr);
  EXPECT_THAT(size, Eq(256));

  auto buffer = std::make_unique<char[]>(size);
  StringBlock* block = StringBlock::Emplace(buffer.get(), size, nullptr);

  ASSERT_THAT(block, Ne(nullptr));
  EXPECT_THAT(block->next(), Eq(nullptr));
  ASSERT_FALSE(block->heap_allocated());
  EXPECT_THAT(block->allocated_size(), Eq(AllocatedSizeFor(256)));
  EXPECT_THAT(block->effective_size(), Eq(EffectiveSizeFor(256)));
  EXPECT_THAT(block->begin(), Eq(block->AtOffset(0)));
  EXPECT_THAT(block->end(), Eq(block->AtOffset(block->effective_size())));

  EXPECT_THAT(StringBlock::Delete(block), Eq(0));
}

TEST(StringBlockTest, HeapAllocateMultipleBlocks) {
  // Note: first two blocks are 256
  StringBlock* previous = StringBlock::New(nullptr);

  for (int size = 256; size <= 8192; size *= 2) {
    StringBlock* block = StringBlock::New(previous);
    ASSERT_THAT(block, Ne(nullptr));
    ASSERT_THAT(block->next(), Eq(previous));
    ASSERT_TRUE(block->heap_allocated());
    ASSERT_THAT(block->allocated_size(), Eq(AllocatedSizeFor(size)));
    ASSERT_THAT(block->effective_size(), Eq(EffectiveSizeFor(size)));
    ASSERT_THAT(block->begin(), Eq(block->AtOffset(0)));
    ASSERT_THAT(block->end(), Eq(block->AtOffset(block->effective_size())));
    previous = block;
  }

  // Capped at 8K from here on
  StringBlock* block = StringBlock::New(previous);
  ASSERT_THAT(block, Ne(nullptr));
  ASSERT_THAT(block->next(), Eq(previous));
  ASSERT_TRUE(block->heap_allocated());
  ASSERT_THAT(block->allocated_size(), Eq(AllocatedSizeFor(8192)));
  ASSERT_THAT(block->effective_size(), Eq(EffectiveSizeFor(8192)));
  ASSERT_THAT(block->begin(), Eq(block->AtOffset(0)));
  ASSERT_THAT(block->end(), Eq(block->AtOffset(block->effective_size())));

  while (block) {
    size_t size = block->allocated_size();
    StringBlock* next = block->next();
    EXPECT_THAT(StringBlock::Delete(block), Eq(AllocatedSizeFor(size)));
    block = next;
  }
}

TEST(StringBlockTest, EmplaceMultipleBlocks) {
  std::vector<std::unique_ptr<char[]>> buffers;

  // Convenience lambda to allocate a buffer and invoke Emplace on it.
  auto EmplaceBlock = [&](StringBlock* previous) {
    size_t size = StringBlock::NextSize(previous);
    buffers.push_back(std::make_unique<char[]>(size));
    return StringBlock::Emplace(buffers.back().get(), size, previous);
  };

  // Note: first two blocks are 256
  StringBlock* previous = EmplaceBlock(nullptr);

  for (int size = 256; size <= 8192; size *= 2) {
    StringBlock* block = EmplaceBlock(previous);
    ASSERT_THAT(block, Ne(nullptr));
    ASSERT_THAT(block->next(), Eq(previous));
    ASSERT_FALSE(block->heap_allocated());
    ASSERT_THAT(block->allocated_size(), Eq(AllocatedSizeFor(size)));
    ASSERT_THAT(block->effective_size(), Eq(EffectiveSizeFor(size)));
    ASSERT_THAT(block->begin(), Eq(block->AtOffset(0)));
    ASSERT_THAT(block->end(), Eq(block->AtOffset(block->effective_size())));
    previous = block;
  }

  // Capped at 8K from here on
  StringBlock* block = EmplaceBlock(previous);
  ASSERT_THAT(block, Ne(nullptr));
  EXPECT_THAT(block->next(), Eq(previous));
  ASSERT_FALSE(block->heap_allocated());
  ASSERT_THAT(block->allocated_size(), Eq(AllocatedSizeFor(8192)));
  ASSERT_THAT(block->effective_size(), Eq(EffectiveSizeFor(8192)));
  ASSERT_THAT(block->begin(), Eq(block->AtOffset(0)));
  ASSERT_THAT(block->end(), Eq(block->AtOffset(block->effective_size())));

  while (block) {
    StringBlock* next = block->next();
    EXPECT_THAT(StringBlock::Delete(block), Eq(0));
    block = next;
  }
}

}  // namespace
}  // namespace internal
}  // namespace protobuf
}  // namespace google

#include "google/protobuf/port_undef.inc"
