// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC.  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

#include "upb/message/array.h"

#include <cstddef>
#include <cstdint>

#include <gtest/gtest.h>
#include "upb/base/descriptor_constants.h"
#include "upb/base/status.hpp"
#include "upb/mem/arena.h"
#include "upb/mem/arena.hpp"

TEST(ArrayTest, ResizeSizeMaxReturnsFalse) {
  upb::Arena arena;
  upb_Array* array = upb_Array_New(arena.ptr(), kUpb_CType_Bool);
  EXPECT_TRUE(array);
  // Resize to SIZE_MAX triggers capacity doubling overflow in
  // _upb_Array_Realloc. The guard rejects SIZE_MAX capacity.
  EXPECT_FALSE(upb_Array_Resize(array, SIZE_MAX, arena.ptr()));
  // Array should still be usable after rejected resize.
  EXPECT_TRUE(upb_Array_Resize(array, 4, arena.ptr()));
  EXPECT_EQ(upb_Array_Size(array), 4);
}

TEST(ArrayTest, Resize) {
  upb::Arena arena;
  upb::Status status;

  upb_Array* array = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  EXPECT_TRUE(array);

  for (int i = 0; i < 10; i++) {
    upb_MessageValue mv;
    mv.int32_val = 3 * i;

    ASSERT_TRUE(upb_Array_Append(array, mv, arena.ptr()));
    EXPECT_EQ(upb_Array_Size(array), i + 1);
    EXPECT_EQ(upb_Array_Get(array, i).int32_val, 3 * i);
  }

  ASSERT_TRUE(upb_Array_Resize(array, 12, arena.ptr()));
  EXPECT_EQ(upb_Array_Get(array, 10).int32_val, 0);
  EXPECT_EQ(upb_Array_Get(array, 11).int32_val, 0);

  ASSERT_TRUE(upb_Array_Resize(array, 4, arena.ptr()));
  EXPECT_EQ(upb_Array_Size(array), 4);

  ASSERT_TRUE(upb_Array_Resize(array, 6, arena.ptr()));
  EXPECT_EQ(upb_Array_Size(array), 6);

  EXPECT_EQ(upb_Array_Get(array, 3).int32_val, 9);
  EXPECT_EQ(upb_Array_Get(array, 4).int32_val, 0);
  EXPECT_EQ(upb_Array_Get(array, 5).int32_val, 0);
}

TEST(ArrayTest, Copy) {
  upb::Arena arena;
  upb_Array* src = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  for (int i = 0; i < 5; i++) {
    upb_MessageValue mv;
    mv.int32_val = i;
    EXPECT_TRUE(upb_Array_Append(src, mv, arena.ptr()));
  }

  upb_Array* dst = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  EXPECT_TRUE(upb_Array_Copy(dst, src, arena.ptr()));
  EXPECT_EQ(upb_Array_Size(dst), 5);
  for (int i = 0; i < 5; i++) {
    EXPECT_EQ(upb_Array_Get(dst, i).int32_val, i);
  }

  // Copy empty array
  upb_Array* empty_src = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  EXPECT_TRUE(upb_Array_Copy(dst, empty_src, arena.ptr()));
  EXPECT_EQ(upb_Array_Size(dst), 0);
}

TEST(ArrayTest, AppendAll) {
  upb::Arena arena;
  upb_Array* dst = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  for (int i = 0; i < 3; i++) {
    upb_MessageValue mv;
    mv.int32_val = i;
    ASSERT_TRUE(upb_Array_Append(dst, mv, arena.ptr()));
  }

  upb_Array* src = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  for (int i = 0; i < 3; i++) {
    upb_MessageValue mv;
    mv.int32_val = i + 10;
    ASSERT_TRUE(upb_Array_Append(src, mv, arena.ptr()));
  }

  EXPECT_TRUE(upb_Array_AppendAll(dst, src, arena.ptr()));
  EXPECT_EQ(upb_Array_Size(dst), 6);
  EXPECT_EQ(upb_Array_Get(dst, 0).int32_val, 0);
  EXPECT_EQ(upb_Array_Get(dst, 1).int32_val, 1);
  EXPECT_EQ(upb_Array_Get(dst, 2).int32_val, 2);
  EXPECT_EQ(upb_Array_Get(dst, 3).int32_val, 10);
  EXPECT_EQ(upb_Array_Get(dst, 4).int32_val, 11);
  EXPECT_EQ(upb_Array_Get(dst, 5).int32_val, 12);

  // Append empty array
  upb_Array* empty_src = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  EXPECT_TRUE(upb_Array_AppendAll(dst, empty_src, arena.ptr()));
  EXPECT_EQ(upb_Array_Size(dst), 6);

  // Append to empty array
  upb_Array* empty_dst = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  EXPECT_TRUE(upb_Array_AppendAll(empty_dst, src, arena.ptr()));
  EXPECT_EQ(upb_Array_Size(empty_dst), 3);
  EXPECT_EQ(upb_Array_Get(empty_dst, 0).int32_val, 10);
}

TEST(ArrayTest, MemoryPooling) {
  // Use an explicit initial size rather than relying on default arena size.
  upb::Arena arena(1024);

  // 1. Create two arrays and interleave appends to prevent TryExtend in-place
  // reuse and populate the pool with freed power-of-2 buffers.
  upb_Array* arr1 = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  upb_Array* arr2 = upb_Array_New(arena.ptr(), kUpb_CType_Int32);

  for (int32_t i = 0; i < 100; i++) {
    upb_MessageValue mv;
    mv.int32_val = i;
    ASSERT_TRUE(upb_Array_Append(arr1, mv, arena.ptr()));
    ASSERT_TRUE(upb_Array_Append(arr2, mv, arena.ptr()));
  }

  size_t space_after = upb_Arena_SpaceAllocated(arena.ptr(), nullptr);

  // 2. Create Array 3 in the same arena and grow it up to 50 elements.
  // It should reuse the buffers freed by arr1 and arr2 from the pool.
  upb_Array* arr3 = upb_Array_New(arena.ptr(), kUpb_CType_Int32);
  for (int32_t i = 0; i < 50; i++) {
    upb_MessageValue mv;
    mv.int32_val = i;
    ASSERT_TRUE(upb_Array_Append(arr3, mv, arena.ptr()));
  }

  size_t space_after_arr3 = upb_Arena_SpaceAllocated(arena.ptr(), nullptr);

  // The difference should only be the Array 3 header (approx 32-48 bytes),
  // because array buffer allocations are reused from the pool.
  size_t diff = space_after_arr3 - space_after;
  EXPECT_LT(diff, 100);
}
