/*
 *
 *    Copyright (c) 2020-2022 Project CHIP Authors
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements a unit test suite for
 *      <tt>chip::System::PacketBuffer</tt>, a class that provides
 *      structure for network packet buffer management.
 */

#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <platform/CHIPDeviceLayer.h>
#include <system/SystemPacketBuffer.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/init.h>
#include <lwip/tcpip.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#if (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
#define PBUF_TYPE(pbuf) (pbuf)->type
#else // (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
#define PBUF_TYPE(pbuf) (pbuf)->type_internal
#endif // (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0)
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

using ::chip::Encoding::PacketBufferWriter;
using ::chip::System::PacketBuffer;
using ::chip::System::PacketBufferHandle;

#if !CHIP_SYSTEM_CONFIG_USE_LWIP
using ::chip::System::pbuf;
#endif

// Utility functions.

#define TO_LWIP_PBUF(x) (reinterpret_cast<struct pbuf *>(reinterpret_cast<void *>(x)))
#define OF_LWIP_PBUF(x) (reinterpret_cast<PacketBuffer *>(reinterpret_cast<void *>(x)))

namespace {
void ScrambleData(uint8_t * start, uint16_t length)
{
    for (uint16_t i = 0; i < length; ++i)
        ++start[i];
}
} // namespace

namespace chip {
namespace System {

/*
 * This class is a friend class of `PacketBuffer` and `PacketBufferHandle` because some tests
 * use or check private methods or properties.
 */
class TestSystemPacketBuffer : public ::testing::Test
{
public:
    static constexpr auto kBlockSize     = PacketBuffer::kBlockSize;
    static constexpr auto kStructureSize = PacketBuffer::kStructureSize;

    static constexpr uint16_t kReservedSizes[] = { 0, 10, 128, 1536, PacketBuffer::kMaxSizeWithoutReserve, kBlockSize };
    static constexpr uint16_t kLengths[]       = { 0, 1, 10, 128, kBlockSize, UINT16_MAX };

    static void SetUpTestSuite()
    {
        ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR);
        ASSERT_EQ(chip::DeviceLayer::PlatformMgr().InitChipStack(), CHIP_NO_ERROR);
    }

    static void TearDownTestSuite()
    {
        chip::DeviceLayer::PlatformMgr().Shutdown();
        chip::Platform::MemoryShutdown();
    }

    void SetUp()
    {
        configurations.resize(0);
        // Set up the buffer configuration vector for this suite.
        for (auto size : kReservedSizes)
        {
            configurations.emplace_back<BufferConfiguration>(size);
        }
    }

    void TearDown()
    {
        ASSERT_TRUE(ResetConfigurations());
        ASSERT_TRUE(ResetHandles());
    }

    static void PrintHandle(const char * tag, const PacketBuffer * buffer)
    {
        printf("%s %p ref=%u len=%-4u next=%p\n", StringOrNullMarker(tag), buffer, buffer ? buffer->ref : 0,
               buffer ? buffer->len : 0, buffer ? buffer->next : nullptr);
    }
    static void PrintHandle(const char * tag, const PacketBufferHandle & handle) { PrintHandle(tag, handle.mBuffer); }

    struct BufferConfiguration
    {
        BufferConfiguration(uint16_t aReservedSize = 0) :
            init_len(0), reserved_size(aReservedSize), start_buffer(nullptr), end_buffer(nullptr), payload_ptr(nullptr),
            handle(nullptr)
        {}

        uint16_t init_len;
        uint16_t reserved_size;
        uint8_t * start_buffer;
        uint8_t * end_buffer;
        uint8_t * payload_ptr;
        PacketBufferHandle handle;
    };

    static void PrintHandle(const char * tag, const BufferConfiguration & config) { PrintHandle(tag, config.handle); }
    static void PrintConfig(const char * tag, const BufferConfiguration & config)
    {
        printf("%s pay=%-4zu len=%-4u res=%-4u:", StringOrNullMarker(tag), config.payload_ptr - config.start_buffer,
               config.init_len, config.reserved_size);
        PrintHandle("", config.handle);
    }

    /*
     * Buffers allocated through PrepareTestBuffer with kRecordHandle set will be recorded in `handles` so that their
     * reference counts can be verified by ResetHandles(). Initially they have two refs: the recorded one and the returned one.
     */
    static constexpr int kRecordHandle     = 0x01;
    static constexpr int kAllowHandleReuse = 0x02;
    void PrepareTestBuffer(BufferConfiguration * config, int flags = 0);

    /*
     * Checks and clears the recorded handles. Returns true if it detects no leaks or double frees.
     * Called from `TerminateTest()`, but tests may choose to call it more often to verify reference counts.
     */
    bool ResetConfigurations();
    bool ResetHandles();

    std::vector<BufferConfiguration> configurations;
    std::vector<PacketBufferHandle> handles;

    void CheckAddRef();
    void CheckAddToEnd();
    void CheckCompactHead();
    void CheckConsume();
    void CheckConsumeHead();
    void CheckDataLength();
    void CheckEnsureReservedSize();
    void CheckFree();
    void CheckFreeHead();
    void CheckHandleAdopt();
    void CheckHandleAdvance();
    void CheckHandleCloneData();
    void CheckHandleConstruct();
    void CheckHandleFree();
    void CheckHandleHold();
    void CheckHandleMove();
    void CheckHandleRelease();
    void CheckHandleRetain();
    void CheckHandleRightSize();
    void CheckLast();
    void CheckNew();
    void CheckNext();
    void CheckPopHead();
    void CheckRead();
    void CheckSetDataLength();
    void CheckSetStart();
};

/*
 * Run fixture's class function as a test.
 */
#define TEST_F_FROM_FIXTURE(test_fixture, test_name)                                                                               \
    TEST_F(test_fixture, test_name)                                                                                                \
    {                                                                                                                              \
        test_name();                                                                                                               \
    }                                                                                                                              \
    void test_fixture::test_name()

/**
 *  Allocate memory for a test buffer and configure according to test buffer configuration.
 */
void TestSystemPacketBuffer::PrepareTestBuffer(BufferConfiguration * config, int flags)
{
    if (config->handle.IsNull())
    {
        config->handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
        if (config->handle.IsNull())
        {
            printf("NewPacketBuffer: Failed to allocate packet buffer (%u retained): %s\n",
                   static_cast<unsigned int>(handles.size()), strerror(errno));
            exit(EXIT_FAILURE);
        }
        if (flags & kRecordHandle)
        {
            handles.push_back(config->handle.Retain());
        }
    }
    else if ((flags & kAllowHandleReuse) == 0)
    {
        printf("Dirty test configuration\n");
        exit(EXIT_FAILURE);
    }

    const size_t lInitialSize = kStructureSize + config->reserved_size;
    const size_t lAllocSize   = kBlockSize;

    uint8_t * const raw = reinterpret_cast<uint8_t *>(config->handle.Get());
    memset(raw + kStructureSize, 0, lAllocSize - kStructureSize);

    config->start_buffer = raw;
    config->end_buffer   = raw + lAllocSize;

    if (lInitialSize > lAllocSize)
    {
        config->payload_ptr = config->end_buffer;
    }
    else
    {
        config->payload_ptr = config->start_buffer + lInitialSize;
    }

    if (config->handle->HasChainedBuffer())
    {
        // This should not happen.
        PacketBuffer::Free(config->handle->ChainedBuffer());
        config->handle->next = nullptr;
    }
    config->handle->payload = config->payload_ptr;
    config->handle->len     = config->init_len;
    config->handle->tot_len = config->init_len;
}

bool TestSystemPacketBuffer::ResetConfigurations()
{
    // Clear the configurations' buffer handles.
    for (auto & configuration : configurations)
        configuration.handle = nullptr;
    return true;
}

bool TestSystemPacketBuffer::ResetHandles()
{
    // Check against leaks or double-frees in tests: every handle obtained through
    // TestSystemPacketBuffer::NewPacketBuffer should have a reference count of 1.
    bool handles_ok = true;
    for (size_t i = 0; i < handles.size(); ++i)
    {
        const PacketBufferHandle & handle = handles[i];
        if (handle.Get() == nullptr)
        {
            printf("TestTerminate: handle %u null\n", static_cast<unsigned int>(i));
            handles_ok = false;
        }
        else if (handle->ref != 1)
        {
            printf("TestTerminate: handle %u buffer=%p ref=%u\n", static_cast<unsigned int>(i), handle.Get(), handle->ref);
            handles_ok = false;
            while (handle->ref > 1)
            {
                PacketBuffer::Free(handle.Get());
            }
        }
    }
    handles.resize(0);
    return handles_ok;
}

/**
 *  Test PacketBufferHandle::New() function.
 *
 *  Description: For every buffer-configuration from inContext, create a buffer's instance
 *               using the New() method. Then, verify that when the size of the reserved space
 *               passed to New() is greater than PacketBuffer::kMaxSizeWithoutReserve,
 *               the method returns nullptr. Otherwise, check for correctness of initializing
 *               the new buffer's internal state.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckNew)
{
    for (const auto & config : configurations)
    {
        const PacketBufferHandle buffer = PacketBufferHandle::New(0, config.reserved_size);

        if (config.reserved_size > PacketBuffer::kMaxSizeWithoutReserve)
        {
            EXPECT_TRUE(buffer.IsNull());
            continue;
        }

        EXPECT_LE(config.reserved_size, buffer->AllocSize());
        ASSERT_FALSE(buffer.IsNull());

        if (!buffer.IsNull())
        {
            // TODO: the code below seems maybe questionable: OF_LWIP_PBUF is never used
            // NOLINTBEGIN(bugprone-casting-through-void)
            const pbuf * const pb = TO_LWIP_PBUF(buffer.Get());
            // NOLINTEND(bugprone-casting-through-void)

            EXPECT_EQ(pb->len, 0);
            EXPECT_EQ(pb->tot_len, 0);
            EXPECT_EQ(pb->next, nullptr);
            EXPECT_EQ(pb->ref, 1);
        }
    }

#if CHIP_SYSTEM_PACKETBUFFER_FROM_LWIP_POOL || CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL
    // Use the rest of the buffer space
    std::vector<PacketBufferHandle> allocate_all_the_things;
    for (;;)
    {
        PacketBufferHandle buffer = PacketBufferHandle::New(0, 0);
        if (buffer.IsNull())
        {
            break;
        }
        // Hold on to the buffer, to use up all the buffer space.
        allocate_all_the_things.push_back(std::move(buffer));
    }
#endif // CHIP_SYSTEM_PACKETBUFFER_FROM_LWIP_POOL || CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL
}

/**
 *  Test PacketBuffer::Start() function.
 */
TEST_F(TestSystemPacketBuffer, CheckStart)
{

    for (auto & config : configurations)
    {
        PrepareTestBuffer(&config, kRecordHandle);
        EXPECT_EQ(config.handle->Start(), config.payload_ptr);
    }
}

/**
 *  Test PacketBuffer::SetStart() function.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance according to the configuration. Next,
 *               for any offset value from start_offset[], pass it to the
 *               buffer's instance through SetStart method. Then, verify that
 *               the beginning of the buffer has been correctly internally
 *               adjusted according to the offset value passed into the
 *               SetStart() method.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckSetStart)
{
    static constexpr ptrdiff_t sSizePacketBuffer = kBlockSize;

    for (auto & config : configurations)
    {
        // clang-format off
        static constexpr ptrdiff_t start_offset[] =
        {
            -sSizePacketBuffer,
            -128,
            -1,
            0,
            1,
            128,
            sSizePacketBuffer
        };
        // clang-format on

        for (ptrdiff_t offset : start_offset)
        {
            PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            uint8_t * const test_start = config.payload_ptr + offset;
            uint8_t * verify_start     = test_start;

            config.handle->SetStart(test_start);

            if (verify_start < config.start_buffer + kStructureSize)
            {
                // Set start before valid payload beginning.
                verify_start = config.start_buffer + kStructureSize;
            }

            if (verify_start > config.end_buffer)
            {
                // Set start after valid payload beginning.
                verify_start = config.end_buffer;
            }

            EXPECT_EQ(config.handle->payload, verify_start);

            if ((verify_start - config.payload_ptr) > config.init_len)
            {
                // Set start to the beginning of payload, right after handle's header.
                EXPECT_EQ(config.handle->len, 0);
            }
            else
            {
                // Set start to somewhere between the end of the handle's
                // header and the end of payload.
                EXPECT_EQ(config.handle->len, (config.init_len - (verify_start - config.payload_ptr)));
            }
        }
    }
}

/**
 *  Test PacketBuffer::DataLength() function.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckDataLength)
{
    for (auto & config : configurations)
    {
        PrepareTestBuffer(&config, kRecordHandle);
        EXPECT_EQ(config.handle->DataLength(), config.handle->len);
    }
}

/**
 *  Test PacketBuffer::SetDataLength() function.
 *
 *  Description: Take two initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. For any two buffers, call SetDataLength with
 *               different value from sLength[]. If two buffers are created with
 *               the same configuration, test SetDataLength on one buffer,
 *               without specifying the head of the buffer chain. Otherwise,
 *               test SetDataLength with one buffer being down the chain and the
 *               other one being passed as the head of the chain. After calling
 *               the method verify that data lengths were correctly adjusted.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckSetDataLength)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            for (auto length : kLengths)
            {
                PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
                PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);

                if (&config_1 == &config_2)
                {
                    // headOfChain (the second arg) is NULL
                    config_2.handle->SetDataLength(length, nullptr);

                    if (length > (config_2.end_buffer - config_2.payload_ptr))
                    {
                        EXPECT_EQ(config_2.handle->len, (config_2.end_buffer - config_2.payload_ptr));
                        EXPECT_EQ(config_2.handle->tot_len, (config_2.end_buffer - config_2.payload_ptr));
                        EXPECT_EQ(config_2.handle->next, nullptr);
                    }
                    else
                    {
                        EXPECT_EQ(config_2.handle->len, length);
                        EXPECT_EQ(config_2.handle->tot_len, length);
                        EXPECT_EQ(config_2.handle->next, nullptr);
                    }
                }
                else
                {
                    // headOfChain (the second arg) is config_1.handle
                    config_2.handle->SetDataLength(length, config_1.handle);

                    if (length > (config_2.end_buffer - config_2.payload_ptr))
                    {
                        EXPECT_EQ(config_2.handle->len, (config_2.end_buffer - config_2.payload_ptr));
                        EXPECT_EQ(config_2.handle->tot_len, (config_2.end_buffer - config_2.payload_ptr));
                        EXPECT_EQ(config_2.handle->next, nullptr);

                        EXPECT_EQ(config_1.handle->tot_len,
                                  (config_1.init_len + static_cast<int32_t>(config_2.end_buffer - config_2.payload_ptr) -
                                   static_cast<int32_t>(config_2.init_len)));
                    }
                    else
                    {
                        EXPECT_EQ(config_2.handle->len, length);
                        EXPECT_EQ(config_2.handle->tot_len, length);
                        EXPECT_EQ(config_2.handle->next, nullptr);

                        EXPECT_EQ(config_1.handle->tot_len,
                                  (config_1.init_len + static_cast<int32_t>(length) - static_cast<int32_t>(config_2.init_len)));
                    }
                }
            }
        }
    }
}

/**
 *  Test PacketBuffer::TotalLength() function.
 */
TEST_F(TestSystemPacketBuffer, CheckTotalLength)
{
    for (auto & config : configurations)
    {
        PrepareTestBuffer(&config, kRecordHandle);
        EXPECT_EQ(config.handle->TotalLength(), config.init_len);
    }
}

/**
 *  Test PacketBuffer::MaxDataLength() function.
 */
TEST_F(TestSystemPacketBuffer, CheckMaxDataLength)
{
    for (auto & config : configurations)
    {
        PrepareTestBuffer(&config, kRecordHandle);
        EXPECT_EQ(config.handle->MaxDataLength(), (config.end_buffer - config.payload_ptr));
    }
}

/**
 *  Test PacketBuffer::AvailableDataLength() function.
 */
TEST_F(TestSystemPacketBuffer, CheckAvailableDataLength)
{
    for (auto & config : configurations)
    {
        PrepareTestBuffer(&config, kRecordHandle);
        EXPECT_EQ(config.handle->AvailableDataLength(), ((config.end_buffer - config.payload_ptr) - config.init_len));
    }
}

/**
 *  Test PacketBuffer::ReservedSize() function.
 */
TEST_F(TestSystemPacketBuffer, CheckReservedSize)
{
    for (auto & config : configurations)
    {
        PrepareTestBuffer(&config, kRecordHandle);
        const size_t kAllocSize = config.handle->AllocSize();

        if (config.reserved_size > kAllocSize)
        {
            EXPECT_EQ(config.handle->ReservedSize(), kAllocSize);
        }
        else
        {
            EXPECT_EQ(config.handle->ReservedSize(), config.reserved_size);
        }
    }
}

/**
 *  Test PacketBuffer::HasChainedBuffer() function.
 */
TEST_F(TestSystemPacketBuffer, CheckHasChainedBuffer)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            PrepareTestBuffer(&config_1);
            PrepareTestBuffer(&config_2);

            EXPECT_FALSE(config_1.handle->HasChainedBuffer());
            EXPECT_FALSE(config_2.handle->HasChainedBuffer());

            config_1.handle->AddToEnd(config_2.handle.Retain());
            EXPECT_TRUE(config_1.handle->HasChainedBuffer());
            EXPECT_FALSE(config_2.handle->HasChainedBuffer());

            config_1.handle = nullptr;
            config_2.handle = nullptr;
        }
    }
}

/**
 *  Test PacketBuffer::AddToEnd() function.
 *
 *  Description: Take three initial configurations of PacketBuffer from
 *               inContext, create three PacketBuffers based on those
 *               configurations and then link those buffers together with
 *               PacketBuffer:AddToEnd(). Then, assert that after connecting
 *               buffers together, their internal states are correctly updated.
 *               This test function tests linking any combination of three
 *               buffer-configurations passed within inContext.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckAddToEnd)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            for (auto & config_3 : configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                PrepareTestBuffer(&config_1);
                PrepareTestBuffer(&config_2);
                PrepareTestBuffer(&config_3);
                EXPECT_EQ(config_1.handle->ref, 1);
                EXPECT_EQ(config_2.handle->ref, 1);
                EXPECT_EQ(config_3.handle->ref, 1);

                config_1.handle->AddToEnd(config_2.handle.Retain());
                EXPECT_EQ(config_1.handle->ref, 1); // config_1.handle
                EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and config_1.handle->next
                EXPECT_EQ(config_3.handle->ref, 1); // config_3.handle

                EXPECT_EQ(config_1.handle->tot_len, (config_1.init_len + config_2.init_len));
                EXPECT_EQ(config_1.handle->next, config_2.handle.Get());
                EXPECT_EQ(config_2.handle->next, nullptr);
                EXPECT_EQ(config_3.handle->next, nullptr);

                config_1.handle->AddToEnd(config_3.handle.Retain());
                EXPECT_EQ(config_1.handle->ref, 1); // config_1.handle
                EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and config_1.handle->next
                EXPECT_EQ(config_3.handle->ref, 2); // config_3.handle and config_2.handle->next

                EXPECT_EQ(config_1.handle->tot_len, (config_1.init_len + config_2.init_len + config_3.init_len));
                EXPECT_EQ(config_1.handle->next, config_2.handle.Get());
                EXPECT_EQ(config_2.handle->next, config_3.handle.Get());
                EXPECT_EQ(config_3.handle->next, nullptr);

                config_1.handle = nullptr;
                config_2.handle = nullptr;
                config_3.handle = nullptr;
            }
        }
    }
}

/**
 *  Test PacketBuffer::PopHead() function.
 *
 *  Description: Take two initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, link those buffers together, with the first
 *               buffer instance pointing to the second one. Then, call PopHead()
 *               on the first buffer to unlink the second buffer. After the call,
 *               verify correct internal state of the first buffer.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckPopHead)
{
    // Single buffer test.
    for (auto & config_1 : configurations)
    {
        PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
        EXPECT_EQ(config_1.handle->ref, 2);

        const PacketBuffer * const buffer_1 = config_1.handle.mBuffer;

        const PacketBufferHandle popped = config_1.handle.PopHead();

        EXPECT_TRUE(config_1.handle.IsNull());
        EXPECT_EQ(popped.mBuffer, buffer_1);
        EXPECT_EQ(popped->next, nullptr);
        EXPECT_EQ(popped->tot_len, config_1.init_len);
        EXPECT_EQ(popped->ref, 2);
    }

    ResetHandles();

    // Chained buffers test.
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
            PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);

            config_1.handle->AddToEnd(config_2.handle.Retain());

            const PacketBufferHandle popped = config_1.handle.PopHead();

            EXPECT_EQ(config_1.handle, config_2.handle);
            EXPECT_EQ(config_1.handle->next, nullptr);
            EXPECT_EQ(config_1.handle->tot_len, config_1.init_len);
        }
    }
}

/**
 *  Test PacketBuffer::CompactHead() function.
 *
 *  Description: Take two initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, set both buffers' data length to any
 *               combination of values from sLengths[] and link those buffers
 *               into a chain. Then, call CompactHead() on the first buffer in
 *               the chain. After calling the method, verify correctly adjusted
 *               state of the first buffer.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckCompactHead)
{
    // Single buffer test.
    for (auto & config : configurations)
    {
        for (auto length : kLengths)
        {
            PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            config.handle->SetDataLength(length, config.handle);
            const uint16_t data_length = config.handle->DataLength();

            config.handle->CompactHead();

            EXPECT_EQ(config.handle->payload, (config.start_buffer + kStructureSize));
            EXPECT_EQ(config.handle->tot_len, data_length);
        }

        config.handle = nullptr;
    }

    EXPECT_TRUE(ResetHandles());

    // Chained buffers test.
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            // start with various initial length for the first buffer
            for (auto length_1 : kLengths)
            {
                // start with various initial length for the second buffer
                for (auto length_2 : kLengths)
                {
                    PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
                    EXPECT_EQ(config_1.handle->ref, 2);

                    // CompactHead requires that there be no other references to the chained buffer,
                    // so we manage it manually.
                    PrepareTestBuffer(&config_2);
                    EXPECT_EQ(config_2.handle->ref, 1);
                    PacketBuffer * buffer_2 = std::move(config_2.handle).UnsafeRelease();
                    EXPECT_TRUE(config_2.handle.IsNull());

                    config_1.handle->SetDataLength(length_1, config_1.handle);
                    const uint16_t data_length_1 = config_1.handle->DataLength();

                    // This chain will cause buffer_2 to be freed.
                    config_1.handle->next = buffer_2;

                    // Add various lengths to the second buffer
                    buffer_2->SetDataLength(length_2, config_1.handle);
                    const uint16_t data_length_2 = buffer_2->DataLength();

                    config_1.handle->CompactHead();

                    EXPECT_EQ(config_1.handle->payload, (config_1.start_buffer + kStructureSize));

                    if (config_1.handle->tot_len > config_1.handle->MaxDataLength())
                    {
                        EXPECT_EQ(config_1.handle->len, config_1.handle->MaxDataLength());
                        EXPECT_EQ(buffer_2->len, config_1.handle->tot_len - config_1.handle->MaxDataLength());
                        EXPECT_EQ(config_1.handle->next, buffer_2);
                        EXPECT_EQ(config_1.handle->ref, 2);
                        EXPECT_EQ(buffer_2->ref, 1);
                    }
                    else
                    {
                        EXPECT_EQ(config_1.handle->len, config_1.handle->tot_len);
                        if (data_length_1 >= config_1.handle->MaxDataLength() && data_length_2 == 0)
                        {
                            /* make sure the second buffer is not freed */
                            EXPECT_EQ(config_1.handle->next, buffer_2);
                            EXPECT_EQ(buffer_2->ref, 1);
                        }
                        else
                        {
                            /* make sure the second buffer is freed */
                            EXPECT_EQ(config_1.handle->next, nullptr);
                            buffer_2 = nullptr;
                        }
                    }

                    EXPECT_EQ(config_1.handle->ref, 2);
                    config_1.handle = nullptr;

                    // Verify and release handles.
                    EXPECT_TRUE(ResetHandles());
                }
            }
        }
    }
}

/**
 *  Test PacketBuffer::ConsumeHead() function.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance according to the configuration. Next,
 *               for any value from sLengths[], pass it to the buffer's
 *               instance through ConsumeHead() method. Then, verify that
 *               the internal state of the buffer has been correctly
 *               adjusted according to the value passed into the method.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckConsumeHead)
{
    for (auto & config : configurations)
    {
        for (auto length : kLengths)
        {
            PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);

            config.handle->ConsumeHead(length);

            if (length > config.init_len)
            {
                EXPECT_EQ(config.handle->payload, (config.payload_ptr + config.init_len));
                EXPECT_EQ(config.handle->len, 0);
                EXPECT_EQ(config.handle->tot_len, 0);
            }
            else
            {
                EXPECT_EQ(config.handle->payload, (config.payload_ptr + length));
                EXPECT_EQ(config.handle->len, (config.handle->len - length));
                EXPECT_EQ(config.handle->tot_len, (config.handle->tot_len - length));
            }
        }
    }
}

/**
 *  Test PacketBuffer::Consume() function.
 *
 *  Description: Take two different initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, set both buffers' data length to any
 *               combination of values from sLengths[]  and link those buffers
 *               into a chain. Then, call Consume() on the first buffer in
 *               the chain with all values from sLengths[]. After calling the
 *               method, verify correctly adjusted the state of the first
 *               buffer and appropriate return pointer from the method's call.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckConsume)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            // consume various amounts of memory
            for (auto consumeLength : kLengths)
            {
                // start with various initial length for the first buffer
                for (auto len_1 : kLengths)
                {
                    // start with various initial length for the second buffer
                    for (auto len_2 : kLengths)
                    {
                        PrepareTestBuffer(&config_1);
                        PrepareTestBuffer(&config_2);
                        EXPECT_EQ(config_1.handle->ref, 1);
                        EXPECT_EQ(config_2.handle->ref, 1);

                        config_1.handle->AddToEnd(config_2.handle.Retain());

                        // Add various lengths to buffers
                        config_1.handle->SetDataLength(len_1, config_1.handle);
                        config_2.handle->SetDataLength(len_2, config_1.handle);

                        const uint16_t buf_1_len = config_1.handle->len;
                        const uint16_t buf_2_len = config_2.handle->len;

                        PacketBufferHandle original_handle_1 = config_1.handle.Retain();
                        EXPECT_EQ(config_1.handle->ref, 2); // config_1.handle and original_handle_1
                        EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and config_1.handle->next

                        config_1.handle.Consume(consumeLength);

                        if (consumeLength == 0)
                        {
                            EXPECT_EQ(config_1.handle, original_handle_1);
                            EXPECT_EQ(config_1.handle->len, buf_1_len);
                            EXPECT_EQ(config_2.handle->len, buf_2_len);
                            EXPECT_EQ(config_1.handle->ref, 2); // config_1.handle and original_handle_1
                            EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and config_1.handle->next
                        }
                        else if (consumeLength < buf_1_len)
                        {
                            EXPECT_EQ(config_1.handle, original_handle_1);
                            EXPECT_EQ(config_1.handle->len, buf_1_len - consumeLength);
                            EXPECT_EQ(config_2.handle->len, buf_2_len);
                            EXPECT_EQ(config_1.handle->ref, 2); // config_1.handle and original_handle_1
                            EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and config_1.handle->next
                        }
                        else if ((consumeLength < buf_1_len + buf_2_len ||
                                  (consumeLength == buf_1_len + buf_2_len && buf_2_len == 0)))
                        {
                            EXPECT_EQ(config_1.handle, config_2.handle);
                            EXPECT_EQ(config_2.handle->len, buf_1_len + buf_2_len - consumeLength);
                            EXPECT_EQ(original_handle_1->ref, 1); // original_handle_1
                            EXPECT_EQ(config_2.handle->ref, 2);   // config_1.handle and config_2.handle
                        }
                        else
                        {
                            EXPECT_TRUE(config_1.handle.IsNull());
                            EXPECT_EQ(original_handle_1->ref, 1); // original_handle_1
                            EXPECT_EQ(config_2.handle->ref, 1);   // config_2.handle
                        }

                        original_handle_1 = nullptr;
                        config_1.handle   = nullptr;
                        config_2.handle   = nullptr;
                    }
                }
            }
        }
    }
}

/**
 *  Test PacketBuffer::EnsureReservedSize() function.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance according to the configuration. Next,
 *               manually specify how much space is reserved in the buffer.
 *               Then, verify that EnsureReservedSize() method correctly
 *               retrieves the amount of the reserved space.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckEnsureReservedSize)
{
    for (auto & config : configurations)
    {
        for (auto length : kLengths)
        {
            PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            const uint16_t kAllocSize = config.handle->AllocSize();
            uint16_t reserved_size    = config.reserved_size;

            if (kStructureSize + config.reserved_size > kAllocSize)
            {
                reserved_size = static_cast<uint16_t>(kAllocSize - kStructureSize);
            }

            if (length <= reserved_size)
            {
                EXPECT_EQ(config.handle->EnsureReservedSize(length), true);
                continue;
            }

            if ((length + config.init_len) > (kAllocSize - kStructureSize))
            {
                EXPECT_FALSE(config.handle->EnsureReservedSize(length));
                continue;
            }

            EXPECT_EQ(config.handle->EnsureReservedSize(length), true);
            EXPECT_EQ(config.handle->payload, (config.payload_ptr + length - reserved_size));
        }
    }
}

/**
 *  Test PacketBuffer::AlignPayload() function.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance according to the configuration. Next,
 *               manually specify how much space is reserved and the
 *               required payload shift. Then, verify that AlignPayload()
 *               method correctly aligns the payload start pointer.
 */
TEST_F(TestSystemPacketBuffer, CheckAlignPayload)
{
    for (auto & config : configurations)
    {
        for (auto length : kLengths)
        {
            PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            const uint16_t kAllocSize = config.handle->AllocSize();

            if (length == 0)
            {
                EXPECT_FALSE(config.handle->AlignPayload(length));
                continue;
            }

            uint16_t reserved_size = config.reserved_size;
            if (config.reserved_size > kAllocSize)
            {
                reserved_size = kAllocSize;
            }

            const uint16_t payload_offset = static_cast<uint16_t>(reinterpret_cast<uintptr_t>(config.handle->Start()) % length);
            uint16_t payload_shift        = 0;
            if (payload_offset > 0)
                payload_shift = static_cast<uint16_t>(length - payload_offset);

            if (payload_shift <= kAllocSize - reserved_size)
            {
                EXPECT_EQ(config.handle->AlignPayload(length), true);
                EXPECT_EQ(((unsigned long) config.handle->Start() % length), 0UL);
            }
            else
            {
                EXPECT_FALSE(config.handle->AlignPayload(length));
            }
        }
    }
}

/**
 *  Test PacketBuffer::Next() function.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckNext)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
            PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);

            if (&config_1 != &config_2)
            {
                EXPECT_TRUE(config_1.handle->Next().IsNull());

                config_1.handle->AddToEnd(config_2.handle.Retain());

                EXPECT_EQ(config_1.handle->Next(), config_2.handle);
                EXPECT_EQ(config_1.handle->ChainedBuffer(), config_2.handle.Get());
            }
            else
            {
                EXPECT_FALSE(config_1.handle->HasChainedBuffer());
            }

            EXPECT_FALSE(config_2.handle->HasChainedBuffer());
        }
    }
}

/**
 *  Test PacketBuffer::Last() function.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckLast)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            for (auto & config_3 : configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                PrepareTestBuffer(&config_1);
                PrepareTestBuffer(&config_2);
                PrepareTestBuffer(&config_3);

                EXPECT_EQ(config_1.handle->Last(), config_1.handle);
                EXPECT_EQ(config_2.handle->Last(), config_2.handle);
                EXPECT_EQ(config_3.handle->Last(), config_3.handle);

                config_1.handle->AddToEnd(config_2.handle.Retain());

                EXPECT_EQ(config_1.handle->Last(), config_2.handle);
                EXPECT_EQ(config_2.handle->Last(), config_2.handle);
                EXPECT_EQ(config_3.handle->Last(), config_3.handle);

                config_1.handle->AddToEnd(config_3.handle.Retain());

                EXPECT_EQ(config_1.handle->Last(), config_3.handle);
                EXPECT_EQ(config_2.handle->Last(), config_3.handle);
                EXPECT_EQ(config_3.handle->Last(), config_3.handle);

                config_1.handle = nullptr;
                config_2.handle = nullptr;
                config_3.handle = nullptr;
            }
        }
    }
}

/**
 *  Test PacketBuffer::Read() function.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckRead)
{
    uint8_t payloads[2 * kBlockSize] = { 1 };
    uint8_t result[2 * kBlockSize];
    for (size_t i = 1; i < sizeof(payloads); ++i)
    {
        payloads[i] = static_cast<uint8_t>(random());
    }

    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            PrepareTestBuffer(&config_1, kAllowHandleReuse);
            PrepareTestBuffer(&config_2, kAllowHandleReuse);

            const uint16_t length_1     = config_1.handle->MaxDataLength();
            const uint16_t length_2     = config_2.handle->MaxDataLength();
            const size_t length_sum     = length_1 + length_2;
            const uint16_t length_total = static_cast<uint16_t>(length_sum);
            EXPECT_EQ(length_total, length_sum);

            memcpy(config_1.handle->Start(), payloads, length_1);
            memcpy(config_2.handle->Start(), payloads + length_1, length_2);
            config_1.handle->SetDataLength(length_1);
            config_2.handle->SetDataLength(length_2);
            config_1.handle->AddToEnd(config_2.handle.Retain());
            EXPECT_EQ(config_1.handle->TotalLength(), length_total);

            if (length_1 >= 1)
            {
                // Check a read that does not span packet buffers.
                CHIP_ERROR err = config_1.handle->Read(result, 1);
                EXPECT_EQ(err, CHIP_NO_ERROR);
                EXPECT_EQ(result[0], payloads[0]);
            }

            // Check a read that spans packet buffers.
            CHIP_ERROR err = config_1.handle->Read(result, length_total);
            EXPECT_EQ(err, CHIP_NO_ERROR);
            EXPECT_EQ(memcmp(payloads, result, length_total), 0);

            // Check a read that is too long fails.
            err = config_1.handle->Read(result, length_total + 1);
            EXPECT_EQ(err, CHIP_ERROR_BUFFER_TOO_SMALL);

            // Check that running off the end of a corrupt buffer chain is detected.
            if (length_total < UINT16_MAX)
            {
                // First case: TotalLength() is wrong.
                config_1.handle->tot_len = static_cast<uint16_t>(config_1.handle->tot_len + 1);
                err                      = config_1.handle->Read(result, length_total + 1);
                EXPECT_EQ(err, CHIP_ERROR_INTERNAL);
                config_1.handle->tot_len = static_cast<uint16_t>(config_1.handle->tot_len - 1);
            }
            if (length_1 >= 1)
            {
                // Second case: an individual buffer's DataLength() is wrong.
                config_1.handle->len = static_cast<uint16_t>(config_1.handle->len - 1);
                err                  = config_1.handle->Read(result, length_total);
                EXPECT_EQ(err, CHIP_ERROR_INTERNAL);
                config_1.handle->len = static_cast<uint16_t>(config_1.handle->len + 1);
            }

            config_1.handle = nullptr;
            config_2.handle = nullptr;
        }
    }
}

/**
 *  Test PacketBuffer::AddRef() function.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckAddRef)
{
    for (auto & config : configurations)
    {
        PrepareTestBuffer(&config, kRecordHandle);
        const auto refs = config.handle->ref;
        config.handle->AddRef();
        EXPECT_EQ(config.handle->ref, refs + 1);
        config.handle->ref = refs; // Don't leak buffers.
    }
}

/**
 *  Test PacketBuffer::Free() function.
 *
 *  Description: Take two different initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, chain two buffers together and set each
 *               buffer's reference count to one of the values from
 *               init_ret_count[]. Then, call Free() on the first buffer in
 *               the chain and verify correctly adjusted states of the two
 *               buffers.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckFree)
{
    const decltype(PacketBuffer::ref) init_ref_count[] = { 1, 2, 3 };
    constexpr size_t kRefs                             = sizeof(init_ref_count) / sizeof(init_ref_count[0]);

    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            // start with various buffer ref counts
            for (size_t r = 0; r < kRefs; r++)
            {
                config_1.handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
                config_2.handle = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
                ASSERT_FALSE(config_1.handle.IsNull());
                ASSERT_FALSE(config_2.handle.IsNull());

                PrepareTestBuffer(&config_1, kAllowHandleReuse);
                PrepareTestBuffer(&config_2, kAllowHandleReuse);
                EXPECT_EQ(config_1.handle->ref, 1);
                EXPECT_EQ(config_2.handle->ref, 1);

                // Chain buffers.
                config_1.handle->next = config_2.handle.Get();

                // Add various buffer ref counts.
                const auto initial_refs_1 = config_1.handle->ref = init_ref_count[r];
                const auto initial_refs_2 = config_2.handle->ref = init_ref_count[(r + 1) % kRefs];

                // Free head.
                PacketBuffer::Free(config_1.handle.mBuffer);
                if (initial_refs_1 == 1)
                {
                    config_1.handle.mBuffer = nullptr;
                }

                // Verification.
                if (initial_refs_1 > 1)
                {
                    // Verify that head ref count is decremented.
                    EXPECT_EQ(config_1.handle->ref, initial_refs_1 - 1);
                    // Verify that chain is maintained.
                    EXPECT_EQ(config_1.handle->next, config_2.handle.Get());
                    // Verify that chained buffer ref count has not changed.
                    EXPECT_EQ(config_2.handle->ref, initial_refs_2);
                }
                else
                {
                    if (initial_refs_2 > 1)
                    {
                        // Verify that chained buffer ref count is decremented.
                        EXPECT_EQ(config_2.handle->ref, initial_refs_2 - 1);
                    }
                    else
                    {
                        // Since the test used fake ref counts, config_2.handle now points
                        // to a freed buffer; clear the handle's internal pointer.
                        config_2.handle.mBuffer = nullptr;
                    }
                }

                // Clean up.
                if (!config_1.handle.IsNull())
                {
                    config_1.handle->next = nullptr;
                    config_1.handle->ref  = 1;
                    config_1.handle       = nullptr;
                }
                if (!config_2.handle.IsNull())
                {
                    config_2.handle->ref = 1;
                    config_2.handle      = nullptr;
                }
            }
        }
    }
}

/**
 *  Test PacketBuffer::FreeHead() function.
 *
 *  Description: Take two different initial configurations of PacketBuffer from
 *               inContext and create two PacketBuffer instances based on those
 *               configurations. Next, chain two buffers together. Then, call
 *               FreeHead() on the first buffer in the chain and verify that
 *               the method returned pointer to the second buffer.
 */
TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckFreeHead)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            // Test PacketBuffer::FreeHead

            PrepareTestBuffer(&config_1, kAllowHandleReuse);
            PrepareTestBuffer(&config_2, kAllowHandleReuse);
            EXPECT_EQ(config_1.handle->ref, 1);
            EXPECT_EQ(config_2.handle->ref, 1);

            PacketBufferHandle handle_1 = config_1.handle.Retain();
            config_1.handle->AddToEnd(config_2.handle.Retain());
            EXPECT_EQ(config_1.handle->ref, 2);
            EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and config_1.handle->next

            PacketBuffer * const returned = PacketBuffer::FreeHead(std::move(config_1.handle).UnsafeRelease());

            EXPECT_EQ(handle_1->ref, 1);
            EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and returned
            EXPECT_EQ(returned, config_2.handle.Get());

            config_1.handle = nullptr;
            EXPECT_EQ(config_2.handle->ref, 2);
            config_2.handle = nullptr;
            EXPECT_EQ(returned->ref, 1);
            PacketBuffer::Free(returned);

            // Test PacketBufferHandle::FreeHead

            PrepareTestBuffer(&config_1, kAllowHandleReuse);
            PrepareTestBuffer(&config_2, kAllowHandleReuse);
            EXPECT_EQ(config_1.handle->ref, 1);
            EXPECT_EQ(config_2.handle->ref, 1);

            handle_1 = config_1.handle.Retain();
            config_1.handle->AddToEnd(config_2.handle.Retain());
            EXPECT_EQ(config_1.handle->ref, 2);
            EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and config_1.handle->next

            PacketBuffer * const buffer_1 = config_1.handle.Get();

            config_1.handle.FreeHead();

            EXPECT_EQ(buffer_1->ref, 1);
            EXPECT_EQ(config_1.handle, config_2.handle);
            EXPECT_EQ(config_2.handle->ref, 2); // config_2.handle and config_1.handle

            config_1.handle = nullptr;
            config_2.handle = nullptr;
        }
    }
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleConstruct)
{
    PacketBufferHandle handle_1;
    EXPECT_TRUE(handle_1.IsNull());

    PacketBufferHandle handle_2(nullptr);
    EXPECT_TRUE(handle_2.IsNull());

    PacketBufferHandle handle_3(PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize));
    ASSERT_FALSE(handle_3.IsNull());

    // Private constructor.
    PacketBuffer * const buffer_3 = std::move(handle_3).UnsafeRelease();
    PacketBufferHandle handle_4(buffer_3);
    EXPECT_EQ(handle_4.Get(), buffer_3);
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleMove)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            PrepareTestBuffer(&config_1, kRecordHandle);
            PrepareTestBuffer(&config_2, kRecordHandle);

            const PacketBuffer * const buffer_1 = config_1.handle.Get();
            const PacketBuffer * const buffer_2 = config_2.handle.Get();
            EXPECT_NE(buffer_1, buffer_2);
            EXPECT_EQ(buffer_1->ref, 2); // test.handles and config_1.handle
            EXPECT_EQ(buffer_2->ref, 2); // test.handles and config_2.handle

            config_1.handle = std::move(config_2.handle);
            EXPECT_EQ(config_1.handle.Get(), buffer_2);
            EXPECT_EQ(config_2.handle.Get(), nullptr);
            EXPECT_EQ(buffer_1->ref, 1); // test.handles
            EXPECT_EQ(buffer_2->ref, 2); // test.handles and config_1.handle

            config_1.handle = nullptr;
        }
        // Verify and release handles.
        EXPECT_TRUE(ResetHandles());
    }
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleRelease)
{
    for (auto & config_1 : configurations)
    {
        PrepareTestBuffer(&config_1);

        PacketBuffer * const buffer_1 = config_1.handle.Get();
        PacketBuffer * const taken_1  = std::move(config_1.handle).UnsafeRelease();

        EXPECT_EQ(buffer_1, taken_1);
        EXPECT_TRUE(config_1.handle.IsNull());
        EXPECT_EQ(buffer_1->ref, 1);
        PacketBuffer::Free(buffer_1);
    }
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleFree)
{
    for (auto & config_1 : configurations)
    {
        PrepareTestBuffer(&config_1, kRecordHandle);

        const PacketBuffer * const buffer_1 = config_1.handle.Get();
        EXPECT_EQ(buffer_1->ref, 2); // test.handles and config_1.handle

        config_1.handle = nullptr;
        EXPECT_TRUE(config_1.handle.IsNull());
        EXPECT_EQ(config_1.handle.Get(), nullptr);
        EXPECT_EQ(buffer_1->ref, 1); // test.handles only
    }
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleRetain)
{
    for (auto & config_1 : configurations)
    {
        PrepareTestBuffer(&config_1, kRecordHandle);

        EXPECT_EQ(config_1.handle->ref, 2); // test.handles and config_1.handle

        PacketBufferHandle handle_1 = config_1.handle.Retain();

        EXPECT_EQ(config_1.handle, handle_1);
        EXPECT_EQ(config_1.handle->ref, 3); // test.handles and config_1.handle and handle_1
    }
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleAdopt)
{
    for (auto & config_1 : configurations)
    {
        PrepareTestBuffer(&config_1, kRecordHandle);
        PacketBuffer * buffer_1 = std::move(config_1.handle).UnsafeRelease();

        EXPECT_TRUE(config_1.handle.IsNull());
        EXPECT_EQ(buffer_1->ref, 2); // test.handles and buffer_1

        config_1.handle = PacketBufferHandle::Adopt(buffer_1);
        EXPECT_EQ(config_1.handle.Get(), buffer_1);
        EXPECT_EQ(config_1.handle->ref, 2); // test.handles and config_1.handle

        config_1.handle = nullptr;
        EXPECT_TRUE(config_1.handle.IsNull());
        EXPECT_EQ(buffer_1->ref, 1); // test.handles only
    }
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleHold)
{
    for (auto & config_1 : configurations)
    {
        PrepareTestBuffer(&config_1, kRecordHandle);
        PacketBuffer * buffer_1 = std::move(config_1.handle).UnsafeRelease();

        EXPECT_TRUE(config_1.handle.IsNull());
        EXPECT_EQ(buffer_1->ref, 2); // test.handles and buffer_1

        config_1.handle = PacketBufferHandle::Hold(buffer_1);
        EXPECT_EQ(config_1.handle.Get(), buffer_1);
        EXPECT_EQ(config_1.handle->ref, 3); // test.handles and config_1.handle and buffer_1

        config_1.handle = nullptr;
        EXPECT_TRUE(config_1.handle.IsNull());
        EXPECT_EQ(buffer_1->ref, 2); // test.handles only and buffer_1

        PacketBuffer::Free(buffer_1);
    }
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleAdvance)
{
    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            for (auto & config_3 : configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                PrepareTestBuffer(&config_1);
                PrepareTestBuffer(&config_2);
                PrepareTestBuffer(&config_3);

                PacketBufferHandle handle_1 = config_1.handle.Retain();
                PacketBufferHandle handle_2 = config_2.handle.Retain();
                PacketBufferHandle handle_3 = config_3.handle.Retain();

                config_1.handle->AddToEnd(config_2.handle.Retain());
                config_1.handle->AddToEnd(config_3.handle.Retain());

                EXPECT_EQ(config_1.handle->ChainedBuffer(), config_2.handle.Get());
                EXPECT_EQ(config_2.handle->ChainedBuffer(), config_3.handle.Get());
                EXPECT_FALSE(config_3.handle->HasChainedBuffer());
                EXPECT_EQ(handle_1->ref, 2); // handle_1 and config_1.handle
                EXPECT_EQ(handle_2->ref, 3); // handle_2 and config_2.handle and config_1.handle->next
                EXPECT_EQ(handle_3->ref, 3); // handle_3 and config_3.handle and config_2.handle->next

                config_1.handle.Advance();

                EXPECT_EQ(config_1.handle, handle_2);
                EXPECT_EQ(handle_1->ref, 1); // handle_1 only
                EXPECT_EQ(handle_2->ref, 4); // handle_2, config_[12].handle, handle_1->next
                EXPECT_EQ(handle_3->ref, 3); // handle_3, config_3.handle, config_2.handle->next

                config_1.handle.Advance();

                EXPECT_EQ(config_1.handle, handle_3);
                EXPECT_EQ(handle_1->ref, 1); // handle_1 only
                EXPECT_EQ(handle_2->ref, 3); // handle_2, config_2.handle, handle_1->next
                EXPECT_EQ(handle_3->ref, 4); // handle_3, config_[13].handle, handle_2->next

                config_1.handle = nullptr;
                config_2.handle = nullptr;
                config_3.handle = nullptr;
            }
        }
    }
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleRightSize)
{
    static const char kPayload[] = "Joy!";
    PacketBufferHandle handle    = PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0);
    PacketBuffer * buffer        = handle.mBuffer;

    memcpy(handle->Start(), kPayload, sizeof kPayload);
    buffer->SetDataLength(sizeof kPayload);
    EXPECT_EQ(handle->ref, 1);

    // RightSize should do nothing if there is another reference to the buffer.
    {
        PacketBufferHandle anotherHandle = handle.Retain();
        handle.RightSize();
        EXPECT_EQ(handle.mBuffer, buffer);
    }

#if CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE

    handle.RightSize();
    EXPECT_NE(handle.mBuffer, buffer);
    EXPECT_EQ(handle->DataLength(), sizeof kPayload);
    EXPECT_EQ(memcmp(handle->Start(), kPayload, sizeof kPayload), 0);

#else // CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE

    // For this configuration, RightSize() does nothing.
    handle.RightSize();
    EXPECT_EQ(handle.mBuffer, buffer);

#endif // CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE
}

TEST_F_FROM_FIXTURE(TestSystemPacketBuffer, CheckHandleCloneData)
{
    uint8_t lPayload[2 * PacketBuffer::kMaxSizeWithoutReserve];
    for (uint8_t & payload : lPayload)
    {
        payload = static_cast<uint8_t>(random());
    }

    for (auto & config_1 : configurations)
    {
        for (auto & config_2 : configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            PrepareTestBuffer(&config_1);
            PrepareTestBuffer(&config_2);

            const uint8_t * payload_1 = lPayload;
            memcpy(config_1.handle->Start(), payload_1, config_1.handle->MaxDataLength());
            config_1.handle->SetDataLength(config_1.handle->MaxDataLength());

            const uint8_t * payload_2 = lPayload + config_1.handle->MaxDataLength();
            memcpy(config_2.handle->Start(), payload_2, config_2.handle->MaxDataLength());
            config_2.handle->SetDataLength(config_2.handle->MaxDataLength());

            // Clone single buffer.
            PacketBufferHandle clone_1 = config_1.handle.CloneData();
            ASSERT_FALSE(clone_1.IsNull());
            EXPECT_EQ(clone_1->DataLength(), config_1.handle->DataLength());
            EXPECT_EQ(memcmp(clone_1->Start(), payload_1, clone_1->DataLength()), 0);
            if (clone_1->DataLength())
            {
                // Verify that modifying the clone does not affect the original.
                ScrambleData(clone_1->Start(), clone_1->DataLength());
                EXPECT_NE(memcmp(clone_1->Start(), payload_1, clone_1->DataLength()), 0);
                EXPECT_EQ(memcmp(config_1.handle->Start(), payload_1, config_1.handle->DataLength()), 0);
            }

            // Clone buffer chain.
            config_1.handle->AddToEnd(config_2.handle.Retain());
            EXPECT_TRUE(config_1.handle->HasChainedBuffer());
            clone_1                         = config_1.handle.CloneData();
            PacketBufferHandle clone_1_next = clone_1->Next();
            ASSERT_FALSE(clone_1.IsNull());
            EXPECT_TRUE(clone_1->HasChainedBuffer());
            EXPECT_EQ(clone_1->DataLength(), config_1.handle->DataLength());
            EXPECT_EQ(clone_1->TotalLength(), config_1.handle->TotalLength());
            EXPECT_EQ(clone_1_next->DataLength(), config_2.handle->DataLength());
            EXPECT_EQ(memcmp(clone_1->Start(), payload_1, clone_1->DataLength()), 0);
            EXPECT_EQ(memcmp(clone_1_next->Start(), payload_2, clone_1_next->DataLength()), 0);
            if (clone_1->DataLength())
            {
                ScrambleData(clone_1->Start(), clone_1->DataLength());
                EXPECT_NE(memcmp(clone_1->Start(), payload_1, clone_1->DataLength()), 0);
                EXPECT_EQ(memcmp(config_1.handle->Start(), payload_1, config_1.handle->DataLength()), 0);
            }
            if (clone_1_next->DataLength())
            {
                ScrambleData(clone_1_next->Start(), clone_1_next->DataLength());
                EXPECT_NE(memcmp(clone_1_next->Start(), payload_2, clone_1_next->DataLength()), 0);
                EXPECT_EQ(memcmp(config_2.handle->Start(), payload_2, config_2.handle->DataLength()), 0);
            }

            config_1.handle = nullptr;
            config_2.handle = nullptr;
        }
    }

#if CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP

    // It is possible for a packet buffer allocation to return a larger block than requested (e.g. when using a shared pool)
    // and in particular to return a larger block than it is possible to request from PackBufferHandle::New().
    // In that case, (a) it is incorrect to actually use the extra space, and (b) if it is not used, the clone will
    // be the maximum possible size.
    //
    // This is only testable on heap allocation configurations, where pbuf records the allocation size and we can manually
    // construct an oversize buffer.

    constexpr uint16_t kOversizeDataSize = PacketBuffer::kMaxSizeWithoutReserve + 99;
    PacketBuffer * p = reinterpret_cast<PacketBuffer *>(chip::Platform::MemoryAlloc(kStructureSize + kOversizeDataSize));
    ASSERT_NE(p, nullptr);

    p->next       = nullptr;
    p->payload    = reinterpret_cast<uint8_t *>(p) + kStructureSize;
    p->tot_len    = 0;
    p->len        = 0;
    p->ref        = 1;
    p->alloc_size = kOversizeDataSize;

    PacketBufferHandle handle = PacketBufferHandle::Adopt(p);

    // Fill the buffer to maximum and verify that it can be cloned.

    memset(handle->Start(), 1, PacketBuffer::kMaxSizeWithoutReserve);
    handle->SetDataLength(PacketBuffer::kMaxSizeWithoutReserve);
    EXPECT_EQ(handle->DataLength(), PacketBuffer::kMaxSizeWithoutReserve);

    PacketBufferHandle clone = handle.CloneData();
    ASSERT_FALSE(clone.IsNull());
    EXPECT_EQ(clone->DataLength(), PacketBuffer::kMaxSizeWithoutReserve);
    EXPECT_EQ(memcmp(handle->Start(), clone->Start(), PacketBuffer::kMaxSizeWithoutReserve), 0);

    // Overfill the buffer and verify that it can not be cloned.
    memset(handle->Start(), 2, kOversizeDataSize);
    handle->SetDataLength(kOversizeDataSize);
    EXPECT_EQ(handle->DataLength(), kOversizeDataSize);

    clone = handle.CloneData();
    EXPECT_TRUE(clone.IsNull());

    // Free the packet buffer memory ourselves, since we allocated it ourselves.
    chip::Platform::MemoryFree(std::move(handle).UnsafeRelease());

#endif // CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP
}

TEST_F(TestSystemPacketBuffer, CheckPacketBufferWriter)
{
    static const char kPayload[] = "Hello, world!";

    PacketBufferWriter yay(PacketBufferHandle::New(sizeof(kPayload)));
    PacketBufferWriter nay(PacketBufferHandle::New(sizeof(kPayload)), sizeof(kPayload) - 2);
    ASSERT_FALSE(yay.IsNull());
    ASSERT_FALSE(nay.IsNull());

    yay.Put(kPayload);
    yay.Put('\0');
    nay.Put(kPayload);
    nay.Put('\0');
    EXPECT_TRUE(yay.Fit());
    EXPECT_FALSE(nay.Fit());

    PacketBufferHandle yayBuffer = yay.Finalize();
    PacketBufferHandle nayBuffer = nay.Finalize();
    EXPECT_TRUE(yay.IsNull());
    EXPECT_TRUE(nay.IsNull());
    ASSERT_FALSE(yayBuffer.IsNull());
    EXPECT_TRUE(nayBuffer.IsNull());
    EXPECT_EQ(memcmp(yayBuffer->Start(), kPayload, sizeof kPayload), 0);
}

} // namespace System
} // namespace chip
