//
// Copyright 2025 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// BufferPoolTestMetal.mm:
//   White box tests for Metal BufferPool allocation logic, specifically for testing
//   size_t overflow scenario.
//

#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

#include "common/apple_platform_utils.h"
#include "common/mathutil.h"
#include "common/unsafe_buffers.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/metal/ContextMtl.h"
#include "libANGLE/renderer/metal/DisplayMtl.h"
#include "libANGLE/renderer/metal/mtl_buffer_pool.h"

using namespace rx;
using namespace angle;

namespace
{

class BufferPoolTest : public ANGLETest<>
{
  protected:
    BufferPoolTest()
    {
        setWindowWidth(1);
        setWindowHeight(1);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    ContextMtl *getContextMtl()
    {
        // Get the context through the display, similar to D3D11 white box tests
        egl::Display *display   = static_cast<egl::Display *>(getEGLWindow()->getDisplay());
        gl::ContextID contextID = {
            static_cast<GLuint>(reinterpret_cast<uintptr_t>(getEGLWindow()->getContext()))};
        gl::Context *context = display->getContext(contextID);
        return mtl::GetImpl(context);
    }
};

// Test that BufferPool correctly handles allocations with size_t offsets > UINT32_MAX
TEST_P(BufferPoolTest, AllocationOffsetNoTruncation)
{
    ANGLE_SKIP_TEST_IF(!IsMetalRendererAvailable());

    // http://anglebug.com/500280351
    ANGLE_SKIP_TEST_IF(IsIOS());

    ContextMtl *contextMtl = getContextMtl();
    ASSERT_NE(contextMtl, nullptr);

    mtl::BufferPool bufferPool;

    // Use a large buffer size that will cause offset calculations to exceed UINT32_MAX
    // when aligned.
    constexpr size_t kLargeSize = 0xFFFFFFFF;  // UINT32_MAX + 512 (4GB bytes)
    constexpr size_t kAlignment = 256;         // Typical Metal buffer alignment
    constexpr size_t kSmallSize = 1024;        // Second allocation size

    // Initialize buffer pool with large initial size
    bufferPool.initialize(contextMtl, kLargeSize, kAlignment, 10);

    // Perform first allocation
    angle::Span<uint8_t> mappedData1;
    mtl::BufferSlice slice1;

    ASSERT_EQ(bufferPool.allocateAndMap(contextMtl, kLargeSize, &mappedData1, &slice1),
              angle::Result::Continue);
    EXPECT_EQ(slice1.offset(), 0u);
    EXPECT_FALSE(mappedData1.empty());
    EXPECT_NE(slice1.buffer(), nullptr);

    // Fill first allocation with a known pattern (0xAA)
    // We only fill the first 4KB to avoid spending too much time on this test
    constexpr size_t kPatternSize = 4096;
    ANGLE_UNSAFE_TODO(memset(mappedData1.data(), 0xAA, kPatternSize));

    // Commit the first allocation to ensure it's written to the buffer
    ASSERT_EQ(bufferPool.commit(contextMtl), angle::Result::Continue);

    // Perform second allocation
    angle::Span<uint8_t> mappedData2;
    mtl::BufferSlice slice2;

    ASSERT_EQ(bufferPool.allocateAndMap(contextMtl, kSmallSize, &mappedData2, &slice2),
              angle::Result::Continue);

    // With the fix (size_t), a new buffer should be allocated since the calculated offset
    // exceeds the buffer size. Otherwise (no fix), the offset would truncate and
    // potentially reuse the same buffer incorrectly, causing memory corruption.
    // The offset should be 0 in the new buffer (not a truncated large value)
    EXPECT_EQ(slice2.offset(), 0u);
    EXPECT_FALSE(mappedData2.empty());
    EXPECT_NE(slice2.buffer(), nullptr);

    // Buffers should be different
    EXPECT_NE(slice1.buffer().get(), slice2.buffer().get());

    // Fill second allocation with a different pattern (0xBB)
    ANGLE_UNSAFE_TODO(memset(mappedData2.data(), 0xBB, kSmallSize));

    // Commit the second allocation
    ASSERT_EQ(bufferPool.commit(contextMtl), angle::Result::Continue);

    // Now verify that the first buffer's data wasn't corrupted
    // With the uint32_t bug, ptr2 would have overwritten ptr1's data at offset 0
    // because the offset wrapped around to 0 or a small value.
    // Map the first buffer again to verify its contents
    angle::Span<const uint8_t> verifyPtr1 = slice1.buffer()->mapReadOnly(contextMtl);
    ASSERT_FALSE(verifyPtr1.empty());

    // Check that the first pattern (0xAA) is still intact
    // If the bug exists, this would have been overwritten with 0xBB
    for (size_t i = 0; i < kSmallSize && i < kPatternSize; ++i)
    {
        EXPECT_EQ(verifyPtr1[i], 0xAA)
            << "First buffer corrupted at byte " << i
            << " - uint32_t truncation bug likely caused second allocation to overlap!";
    }

    slice1.buffer()->unmap(contextMtl);
    bufferPool.destroy(contextMtl);
}

}  // namespace

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BufferPoolTest);
ANGLE_INSTANTIATE_TEST(BufferPoolTest, ES2_METAL(), ES3_METAL());
