/*
 *
 *    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.
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

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

#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/UnitTestContext.h>
#include <lib/support/UnitTestRegistration.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

#include <nlunit-test.h>

#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

/*
 * An instance of this class created for the test suite.
 * It is a friend class of `PacketBuffer` and `PacketBufferHandle` because some tests
 * use or check private methods or properties.
 */
class PacketBufferTest
{
public:
    struct TestContext
    {
        const uint16_t * const reserved_sizes;
        size_t reserved_size_count;
        const uint16_t * const lengths;
        size_t length_count;
        PacketBufferTest * test;
    };

    static int TestSetup(void * inContext);
    static int TestTeardown(void * inContext);
    static int TestInitialize(void * inContext);
    static int TestTerminate(void * inContext);

    static void CheckNew(nlTestSuite * inSuite, void * inContext);
    static void CheckStart(nlTestSuite * inSuite, void * inContext);
    static void CheckSetStart(nlTestSuite * inSuite, void * inContext);
    static void CheckDataLength(nlTestSuite * inSuite, void * inContext);
    static void CheckSetDataLength(nlTestSuite * inSuite, void * inContext);
    static void CheckTotalLength(nlTestSuite * inSuite, void * inContext);
    static void CheckMaxDataLength(nlTestSuite * inSuite, void * inContext);
    static void CheckAvailableDataLength(nlTestSuite * inSuite, void * inContext);
    static void CheckReservedSize(nlTestSuite * inSuite, void * inContext);
    static void CheckHasChainedBuffer(nlTestSuite * inSuite, void * inContext);
    static void CheckAddToEnd(nlTestSuite * inSuite, void * inContext);
    static void CheckPopHead(nlTestSuite * inSuite, void * inContext);
    static void CheckCompactHead(nlTestSuite * inSuite, void * inContext);
    static void CheckConsumeHead(nlTestSuite * inSuite, void * inContext);
    static void CheckConsume(nlTestSuite * inSuite, void * inContext);
    static void CheckEnsureReservedSize(nlTestSuite * inSuite, void * inContext);
    static void CheckAlignPayload(nlTestSuite * inSuite, void * inContext);
    static void CheckNext(nlTestSuite * inSuite, void * inContext);
    static void CheckLast(nlTestSuite * inSuite, void * inContext);
    static void CheckRead(nlTestSuite * inSuite, void * inContext);
    static void CheckAddRef(nlTestSuite * inSuite, void * inContext);
    static void CheckFree(nlTestSuite * inSuite, void * inContext);
    static void CheckFreeHead(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleConstruct(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleMove(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleRelease(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleFree(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleRetain(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleAdopt(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleHold(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleAdvance(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleRightSize(nlTestSuite * inSuite, void * inContext);
    static void CheckHandleCloneData(nlTestSuite * inSuite, void * inContext);
    static void CheckPacketBufferWriter(nlTestSuite * inSuite, void * inContext);
    static void CheckBuildFreeList(nlTestSuite * inSuite, void * inContext);

    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); }

    static constexpr uint16_t kBlockSize = PacketBuffer::kBlockSize;

private:
    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);
    }

    PacketBufferTest(TestContext * context);
    ~PacketBufferTest();

    int InitializeTest(TestContext * context);
    int TerminateTest(TestContext * context);

    /*
     * 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 ResetHandles();

    TestContext * mContext;
    std::vector<BufferConfiguration> configurations;
    std::vector<PacketBufferHandle> handles;
};

const uint16_t sTestReservedSizes[] = { 0, 10, 128, 1536, PacketBuffer::kMaxSizeWithoutReserve, PacketBufferTest::kBlockSize };
const uint16_t sTestLengths[]       = { 0, 1, 10, 128, PacketBufferTest::kBlockSize, UINT16_MAX };

PacketBufferTest::TestContext sContext = {
    sTestReservedSizes,
    sizeof(sTestReservedSizes) / sizeof(uint16_t),
    sTestLengths,
    sizeof(sTestLengths) / sizeof(uint16_t),
};

PacketBufferTest::PacketBufferTest(TestContext * context) : mContext(context)
{
    // Set up the buffer configuration vector for this suite.
    configurations.resize(0);
    for (size_t i = 0; i < mContext->reserved_size_count; ++i)
    {
        configurations.emplace_back<BufferConfiguration>(mContext->reserved_sizes[i]);
    }
}

int PacketBufferTest::TestSetup(void * inContext)
{
    chip::Platform::MemoryInit();

    if (chip::DeviceLayer::PlatformMgr().InitChipStack() != CHIP_NO_ERROR)
        return FAILURE;

    TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
    theContext->test               = new (std::nothrow) PacketBufferTest(theContext);
    if (theContext->test == nullptr)
    {
        return FAILURE;
    }
    return SUCCESS;
}

int PacketBufferTest::TestTeardown(void * inContext)
{
    chip::DeviceLayer::PlatformMgr().Shutdown();

    chip::Platform::MemoryShutdown();

    return SUCCESS;
}

int PacketBufferTest::TestInitialize(void * inContext)
{
    TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
    if (theContext->test == nullptr)
    {
        return FAILURE;
    }
    return theContext->test->InitializeTest(theContext);
}

int PacketBufferTest::InitializeTest(TestContext * context)
{
    if (context != mContext)
    {
        return FAILURE;
    }
    return SUCCESS;
}

int PacketBufferTest::TestTerminate(void * inContext)
{
    TestContext * const theContext = reinterpret_cast<TestContext *>(inContext);
    if (theContext->test == nullptr)
    {
        return FAILURE;
    }
    return theContext->test->TerminateTest(theContext);
}

int PacketBufferTest::TerminateTest(TestContext * context)
{
    const bool context_ok = (context == mContext);
    // Clear the configurations' bufffer handles.
    for (auto & configuration : configurations)
    {
        configuration.handle = nullptr;
    }
    const bool handles_ok = ResetHandles();
    return (context_ok && handles_ok) ? SUCCESS : FAILURE;
}

/**
 *  Allocate memory for a test buffer and configure according to test buffer configuration.
 */
void PacketBufferTest::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 = PacketBuffer::kStructureSize + config->reserved_size;
    const size_t lAllocSize   = kBlockSize;

    uint8_t * const raw = reinterpret_cast<uint8_t *>(config->handle.Get());
    memset(raw + PacketBuffer::kStructureSize, 0, lAllocSize - PacketBuffer::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 PacketBufferTest::ResetHandles()
{
    // Check against leaks or double-frees in tests: every handle obtained through
    // PacketBufferTest::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 functions invoked from the suite.

/**
 *  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.
 */
void PacketBufferTest::CheckNew(nlTestSuite * inSuite, void * inContext)
{
    TestContext * const theContext = static_cast<TestContext *>(inContext);
    PacketBufferTest * const test  = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (const auto & config : test->configurations)
    {
        const PacketBufferHandle buffer = PacketBufferHandle::New(0, config.reserved_size);

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

        NL_TEST_ASSERT(inSuite, config.reserved_size <= buffer->AllocSize());
        NL_TEST_ASSERT(inSuite, !buffer.IsNull());

        if (!buffer.IsNull())
        {
            const pbuf * const pb = TO_LWIP_PBUF(buffer.Get());

            NL_TEST_ASSERT(inSuite, pb->len == 0);
            NL_TEST_ASSERT(inSuite, pb->tot_len == 0);
            NL_TEST_ASSERT(inSuite, pb->next == nullptr);
            NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckStart(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);
        NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckSetStart(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    static constexpr ptrdiff_t sSizePacketBuffer = kBlockSize;

    for (auto & config : test->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)
        {
            test->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 + PacketBuffer::kStructureSize)
            {
                // Set start before valid payload beginning.
                verify_start = config.start_buffer + PacketBuffer::kStructureSize;
            }

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

            NL_TEST_ASSERT(inSuite, 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.
                NL_TEST_ASSERT(inSuite, config.handle->len == 0);
            }
            else
            {
                // Set start to somewhere between the end of the handle's
                // header and the end of payload.
                NL_TEST_ASSERT(inSuite, config.handle->len == (config.init_len - (verify_start - config.payload_ptr)));
            }
        }
    }
}

/**
 *  Test PacketBuffer::DataLength() function.
 */
void PacketBufferTest::CheckDataLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);

        NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckSetDataLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            for (size_t i = 0; i < theContext->length_count; ++i)
            {
                const uint16_t length = theContext->lengths[i];
                test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
                test->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))
                    {
                        NL_TEST_ASSERT(inSuite, config_2.handle->len == (config_2.end_buffer - config_2.payload_ptr));
                        NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == (config_2.end_buffer - config_2.payload_ptr));
                        NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);
                    }
                    else
                    {
                        NL_TEST_ASSERT(inSuite, config_2.handle->len == length);
                        NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == length);
                        NL_TEST_ASSERT(inSuite, 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))
                    {
                        NL_TEST_ASSERT(inSuite, config_2.handle->len == (config_2.end_buffer - config_2.payload_ptr));
                        NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == (config_2.end_buffer - config_2.payload_ptr));
                        NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);

                        NL_TEST_ASSERT(inSuite,
                                       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
                    {
                        NL_TEST_ASSERT(inSuite, config_2.handle->len == length);
                        NL_TEST_ASSERT(inSuite, config_2.handle->tot_len == length);
                        NL_TEST_ASSERT(inSuite, config_2.handle->next == nullptr);

                        NL_TEST_ASSERT(
                            inSuite,
                            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.
 */
void PacketBufferTest::CheckTotalLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);
        NL_TEST_ASSERT(inSuite, config.handle->TotalLength() == config.init_len);
    }
}

/**
 *  Test PacketBuffer::MaxDataLength() function.
 */
void PacketBufferTest::CheckMaxDataLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);

        NL_TEST_ASSERT(inSuite, config.handle->MaxDataLength() == (config.end_buffer - config.payload_ptr));
    }
}

/**
 *  Test PacketBuffer::AvailableDataLength() function.
 */
void PacketBufferTest::CheckAvailableDataLength(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);

        NL_TEST_ASSERT(inSuite,
                       config.handle->AvailableDataLength() == ((config.end_buffer - config.payload_ptr) - config.init_len));
    }
}

/**
 *  Test PacketBuffer::ReservedSize() function.
 */
void PacketBufferTest::CheckReservedSize(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);
        const size_t kAllocSize = config.handle->AllocSize();

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

/**
 *  Test PacketBuffer::HasChainedBuffer() function.
 */
void PacketBufferTest::CheckHasChainedBuffer(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

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

            test->PrepareTestBuffer(&config_1);
            test->PrepareTestBuffer(&config_2);

            NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer() == false);
            NL_TEST_ASSERT(inSuite, config_2.handle->HasChainedBuffer() == false);

            config_1.handle->AddToEnd(config_2.handle.Retain());
            NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer() == true);
            NL_TEST_ASSERT(inSuite, config_2.handle->HasChainedBuffer() == false);

            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.
 */
void PacketBufferTest::CheckAddToEnd(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            for (auto & config_3 : test->configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                test->PrepareTestBuffer(&config_1);
                test->PrepareTestBuffer(&config_2);
                test->PrepareTestBuffer(&config_3);
                NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
                NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
                NL_TEST_ASSERT(inSuite, config_3.handle->ref == 1);

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

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

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

                NL_TEST_ASSERT(inSuite, config_1.handle->tot_len == (config_1.init_len + config_2.init_len + config_3.init_len));
                NL_TEST_ASSERT(inSuite, config_1.handle->next == config_2.handle.Get());
                NL_TEST_ASSERT(inSuite, config_2.handle->next == config_3.handle.Get());
                NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckPopHead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    // Single buffer test.
    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);

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

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

        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, popped.mBuffer == buffer_1);
        NL_TEST_ASSERT(inSuite, popped->next == nullptr);
        NL_TEST_ASSERT(inSuite, popped->tot_len == config_1.init_len);
        NL_TEST_ASSERT(inSuite, popped->ref == 2);
    }
    test->ResetHandles();

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

            test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);

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

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

            NL_TEST_ASSERT(inSuite, config_1.handle == config_2.handle);
            NL_TEST_ASSERT(inSuite, config_1.handle->next == nullptr);
            NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckCompactHead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    // Single buffer test.
    for (auto & config : test->configurations)
    {
        for (size_t i = 0; i < theContext->length_count; ++i)
        {
            const uint16_t length = theContext->lengths[i];

            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            config.handle->SetDataLength(length, config.handle);
            const uint16_t data_length = config.handle->DataLength();

            config.handle->CompactHead();

            NL_TEST_ASSERT(inSuite, config.handle->payload == (config.start_buffer + PacketBuffer::kStructureSize));
            NL_TEST_ASSERT(inSuite, config.handle->tot_len == data_length);
        }

        config.handle = nullptr;
    }
    NL_TEST_ASSERT(inSuite, test->ResetHandles());

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

            // start with various initial length for the first buffer
            for (size_t i = 0; i < theContext->length_count; ++i)
            {
                const uint16_t length_1 = theContext->lengths[i];

                // start with various initial length for the second buffer
                for (size_t j = 0; j < theContext->length_count; ++j)
                {
                    const uint16_t length_2 = theContext->lengths[j];

                    test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
                    NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);

                    // CompactHead requires that there be no other references to the chained buffer,
                    // so we manage it manually.
                    test->PrepareTestBuffer(&config_2);
                    NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);
                    PacketBuffer * buffer_2 = std::move(config_2.handle).UnsafeRelease();
                    NL_TEST_ASSERT(inSuite, 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();

                    NL_TEST_ASSERT(inSuite, config_1.handle->payload == (config_1.start_buffer + PacketBuffer::kStructureSize));

                    if (config_1.handle->tot_len > config_1.handle->MaxDataLength())
                    {
                        NL_TEST_ASSERT(inSuite, config_1.handle->len == config_1.handle->MaxDataLength());
                        NL_TEST_ASSERT(inSuite, buffer_2->len == config_1.handle->tot_len - config_1.handle->MaxDataLength());
                        NL_TEST_ASSERT(inSuite, config_1.handle->next == buffer_2);
                        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
                        NL_TEST_ASSERT(inSuite, buffer_2->ref == 1);
                    }
                    else
                    {
                        NL_TEST_ASSERT(inSuite, 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 */
                            NL_TEST_ASSERT(inSuite, config_1.handle->next == buffer_2);
                            NL_TEST_ASSERT(inSuite, buffer_2->ref == 1);
                        }
                        else
                        {
                            /* make sure the second buffer is freed */
                            NL_TEST_ASSERT(inSuite, config_1.handle->next == nullptr);
                            buffer_2 = nullptr;
                        }
                    }

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

                    // Verify and release handles.
                    NL_TEST_ASSERT(inSuite, test->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.
 */
void PacketBufferTest::CheckConsumeHead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        for (size_t i = 0; i < theContext->length_count; ++i)
        {
            const uint16_t length = theContext->lengths[i];
            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);

            config.handle->ConsumeHead(length);

            if (length > config.init_len)
            {
                NL_TEST_ASSERT(inSuite, config.handle->payload == (config.payload_ptr + config.init_len));
                NL_TEST_ASSERT(inSuite, config.handle->len == 0);
                NL_TEST_ASSERT(inSuite, config.handle->tot_len == 0);
            }
            else
            {
                NL_TEST_ASSERT(inSuite, config.handle->payload == (config.payload_ptr + length));
                NL_TEST_ASSERT(inSuite, config.handle->len == (config.handle->len - length));
                NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckConsume(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

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

            // consume various amounts of memory
            for (size_t i = 0; i < theContext->length_count; ++i)
            {
                const uint16_t consumeLength = theContext->lengths[i];
                // start with various initial length for the first buffer
                for (size_t j = 0; j < theContext->length_count; ++j)
                {
                    const uint16_t len_1 = theContext->lengths[j];
                    // start with various initial length for the second buffer
                    for (size_t k = 0; k < theContext->length_count; ++k)
                    {
                        const uint16_t len_2 = theContext->lengths[k];

                        test->PrepareTestBuffer(&config_1);
                        test->PrepareTestBuffer(&config_2);
                        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
                        NL_TEST_ASSERT(inSuite, 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();
                        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
                        NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next

                        config_1.handle.Consume(consumeLength);

                        if (consumeLength == 0)
                        {
                            NL_TEST_ASSERT(inSuite, config_1.handle == original_handle_1);
                            NL_TEST_ASSERT(inSuite, config_1.handle->len == buf_1_len);
                            NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_2_len);
                            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
                            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2); // config_2.handle and config_1.handle->next
                        }
                        else if (consumeLength < buf_1_len)
                        {
                            NL_TEST_ASSERT(inSuite, config_1.handle == original_handle_1);
                            NL_TEST_ASSERT(inSuite, config_1.handle->len == buf_1_len - consumeLength);
                            NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_2_len);
                            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // config_1.handle and original_handle_1
                            NL_TEST_ASSERT(inSuite, 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)))
                        {
                            NL_TEST_ASSERT(inSuite, config_1.handle == config_2.handle);
                            NL_TEST_ASSERT(inSuite, config_2.handle->len == buf_1_len + buf_2_len - consumeLength);
                            NL_TEST_ASSERT(inSuite, original_handle_1->ref == 1); // original_handle_1
                            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 2);   // config_1.handle and config_2.handle
                        }
                        else
                        {
                            NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
                            NL_TEST_ASSERT(inSuite, original_handle_1->ref == 1); // original_handle_1
                            NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckEnsureReservedSize(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        for (size_t i = 0; i < theContext->length_count; ++i)
        {
            const uint16_t length = theContext->lengths[i];

            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            const uint16_t kAllocSize = config.handle->AllocSize();
            uint16_t reserved_size    = config.reserved_size;

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

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

            if ((length + config.init_len) > (kAllocSize - PacketBuffer::kStructureSize))
            {
                NL_TEST_ASSERT(inSuite, config.handle->EnsureReservedSize(length) == false);
                continue;
            }

            NL_TEST_ASSERT(inSuite, config.handle->EnsureReservedSize(length) == true);
            NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckAlignPayload(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        for (size_t n = 0; n < theContext->length_count; ++n)
        {
            test->PrepareTestBuffer(&config, kRecordHandle | kAllowHandleReuse);
            const uint16_t kAllocSize = config.handle->AllocSize();

            if (theContext->lengths[n] == 0)
            {
                NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == false);
                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()) % theContext->lengths[n]);
            uint16_t payload_shift = 0;
            if (payload_offset > 0)
                payload_shift = static_cast<uint16_t>(theContext->lengths[n] - payload_offset);

            if (payload_shift <= kAllocSize - reserved_size)
            {
                NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == true);
                NL_TEST_ASSERT(inSuite, ((unsigned long) config.handle->Start() % theContext->lengths[n]) == 0);
            }
            else
            {
                NL_TEST_ASSERT(inSuite, config.handle->AlignPayload(theContext->lengths[n]) == false);
            }
        }
    }
}

/**
 *  Test PacketBuffer::Next() function.
 */
void PacketBufferTest::CheckNext(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            test->PrepareTestBuffer(&config_1, kRecordHandle | kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kRecordHandle | kAllowHandleReuse);

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

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

                NL_TEST_ASSERT(inSuite, config_1.handle->Next() == config_2.handle);
                NL_TEST_ASSERT(inSuite, config_1.handle->ChainedBuffer() == config_2.handle.Get());
            }
            else
            {
                NL_TEST_ASSERT(inSuite, !config_1.handle->HasChainedBuffer());
            }

            NL_TEST_ASSERT(inSuite, !config_2.handle->HasChainedBuffer());
        }
    }
}

/**
 *  Test PacketBuffer::Last() function.
 */
void PacketBufferTest::CheckLast(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            for (auto & config_3 : test->configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                test->PrepareTestBuffer(&config_1);
                test->PrepareTestBuffer(&config_2);
                test->PrepareTestBuffer(&config_3);

                NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_1.handle);
                NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_2.handle);
                NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);

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

                NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_2.handle);
                NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_2.handle);
                NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);

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

                NL_TEST_ASSERT(inSuite, config_1.handle->Last() == config_3.handle);
                NL_TEST_ASSERT(inSuite, config_2.handle->Last() == config_3.handle);
                NL_TEST_ASSERT(inSuite, config_3.handle->Last() == config_3.handle);

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

/**
 *  Test PacketBuffer::Read() function.
 */
void PacketBufferTest::CheckRead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    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 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            if (&config_1 == &config_2)
            {
                continue;
            }

            test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
            test->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);
            NL_TEST_ASSERT(inSuite, 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());
            NL_TEST_ASSERT(inSuite, 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);
                NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
                NL_TEST_ASSERT(inSuite, result[0] == payloads[0]);
            }

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

            // Check a read that is too long fails.
            err = config_1.handle->Read(result, length_total + 1);
            NL_TEST_ASSERT(inSuite, 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);
                NL_TEST_ASSERT(inSuite, 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);
                NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckAddRef(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config : test->configurations)
    {
        test->PrepareTestBuffer(&config, kRecordHandle);
        const auto refs = config.handle->ref;
        config.handle->AddRef();
        NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckFree(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    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 : test->configurations)
    {
        for (auto & config_2 : test->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);
                NL_TEST_ASSERT(inSuite, !config_1.handle.IsNull());
                NL_TEST_ASSERT(inSuite, !config_2.handle.IsNull());

                test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
                test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
                NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
                NL_TEST_ASSERT(inSuite, 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.
                    NL_TEST_ASSERT(inSuite, config_1.handle->ref == initial_refs_1 - 1);
                    // Verify that chain is maintained.
                    NL_TEST_ASSERT(inSuite, config_1.handle->next == config_2.handle.Get());
                    // Verify that chained buffer ref count has not changed.
                    NL_TEST_ASSERT(inSuite, config_2.handle->ref == initial_refs_2);
                }
                else
                {
                    if (initial_refs_2 > 1)
                    {
                        // Verify that chained buffer ref count is decremented.
                        NL_TEST_ASSERT(inSuite, 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.
 */
void PacketBufferTest::CheckFreeHead(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

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

            // Test PacketBuffer::FreeHead

            test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);

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

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

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

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

            // Test PacketBufferHandle::FreeHead

            test->PrepareTestBuffer(&config_1, kAllowHandleReuse);
            test->PrepareTestBuffer(&config_2, kAllowHandleReuse);
            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 1);
            NL_TEST_ASSERT(inSuite, config_2.handle->ref == 1);

            handle_1 = config_1.handle.Retain();
            config_1.handle->AddToEnd(config_2.handle.Retain());
            NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2);
            NL_TEST_ASSERT(inSuite, 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();

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

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

void PacketBufferTest::CheckHandleConstruct(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    PacketBufferHandle handle_1;
    NL_TEST_ASSERT(inSuite, handle_1.IsNull());

    PacketBufferHandle handle_2(nullptr);
    NL_TEST_ASSERT(inSuite, handle_2.IsNull());

    PacketBufferHandle handle_3(PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSize));
    NL_TEST_ASSERT(inSuite, !handle_3.IsNull());

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

void PacketBufferTest::CheckHandleMove(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

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

            test->PrepareTestBuffer(&config_1, kRecordHandle);
            test->PrepareTestBuffer(&config_2, kRecordHandle);

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

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

            config_1.handle = nullptr;
        }
        // Verify and release handles.
        NL_TEST_ASSERT(inSuite, test->ResetHandles());
    }
}

void PacketBufferTest::CheckHandleRelease(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1);

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

        NL_TEST_ASSERT(inSuite, buffer_1 == taken_1);
        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 1);
        PacketBuffer::Free(buffer_1);
    }
}

void PacketBufferTest::CheckHandleFree(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle);

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

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

void PacketBufferTest::CheckHandleRetain(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle);

        NL_TEST_ASSERT(inSuite, config_1.handle->ref == 2); // test.handles and config_1.handle

        PacketBufferHandle handle_1 = config_1.handle.Retain();

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

void PacketBufferTest::CheckHandleAdopt(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle);
        PacketBuffer * buffer_1 = std::move(config_1.handle).UnsafeRelease();

        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and buffer_1

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

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

void PacketBufferTest::CheckHandleHold(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        test->PrepareTestBuffer(&config_1, kRecordHandle);
        PacketBuffer * buffer_1 = std::move(config_1.handle).UnsafeRelease();

        NL_TEST_ASSERT(inSuite, config_1.handle.IsNull());
        NL_TEST_ASSERT(inSuite, buffer_1->ref == 2); // test.handles and buffer_1

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

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

        PacketBuffer::Free(buffer_1);
    }
}

void PacketBufferTest::CheckHandleAdvance(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    for (auto & config_1 : test->configurations)
    {
        for (auto & config_2 : test->configurations)
        {
            for (auto & config_3 : test->configurations)
            {
                if (&config_1 == &config_2 || &config_1 == &config_3 || &config_2 == &config_3)
                {
                    continue;
                }

                test->PrepareTestBuffer(&config_1);
                test->PrepareTestBuffer(&config_2);
                test->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());

                NL_TEST_ASSERT(inSuite, config_1.handle->ChainedBuffer() == config_2.handle.Get());
                NL_TEST_ASSERT(inSuite, config_2.handle->ChainedBuffer() == config_3.handle.Get());
                NL_TEST_ASSERT(inSuite, config_3.handle->HasChainedBuffer() == false);
                NL_TEST_ASSERT(inSuite, handle_1->ref == 2); // handle_1 and config_1.handle
                NL_TEST_ASSERT(inSuite, handle_2->ref == 3); // handle_2 and config_2.handle and config_1.handle->next
                NL_TEST_ASSERT(inSuite, handle_3->ref == 3); // handle_3 and config_3.handle and config_2.handle->next

                config_1.handle.Advance();

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

                config_1.handle.Advance();

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

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

void PacketBufferTest::CheckHandleRightSize(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    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);
    NL_TEST_ASSERT(inSuite, handle->ref == 1);

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

#if CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE

    handle.RightSize();
    NL_TEST_ASSERT(inSuite, handle.mBuffer != buffer);
    NL_TEST_ASSERT(inSuite, handle->DataLength() == sizeof kPayload);
    NL_TEST_ASSERT(inSuite, memcmp(handle->Start(), kPayload, sizeof kPayload) == 0);

#else // CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE

    // For this configuration, RightSize() does nothing.
    handle.RightSize();
    NL_TEST_ASSERT(inSuite, handle.mBuffer == buffer);

#endif // CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE
}

void PacketBufferTest::CheckHandleCloneData(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

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

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

            test->PrepareTestBuffer(&config_1);
            test->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();
            NL_TEST_ASSERT(inSuite, !clone_1.IsNull());
            NL_TEST_ASSERT(inSuite, clone_1->DataLength() == config_1.handle->DataLength());
            NL_TEST_ASSERT(inSuite, 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());
                NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) != 0);
                NL_TEST_ASSERT(inSuite, memcmp(config_1.handle->Start(), payload_1, config_1.handle->DataLength()) == 0);
            }

            // Clone buffer chain.
            config_1.handle->AddToEnd(config_2.handle.Retain());
            NL_TEST_ASSERT(inSuite, config_1.handle->HasChainedBuffer());
            clone_1                         = config_1.handle.CloneData();
            PacketBufferHandle clone_1_next = clone_1->Next();
            NL_TEST_ASSERT(inSuite, !clone_1.IsNull());
            NL_TEST_ASSERT(inSuite, clone_1->HasChainedBuffer());
            NL_TEST_ASSERT(inSuite, clone_1->DataLength() == config_1.handle->DataLength());
            NL_TEST_ASSERT(inSuite, clone_1->TotalLength() == config_1.handle->TotalLength());
            NL_TEST_ASSERT(inSuite, clone_1_next->DataLength() == config_2.handle->DataLength());
            NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) == 0);
            NL_TEST_ASSERT(inSuite, memcmp(clone_1_next->Start(), payload_2, clone_1_next->DataLength()) == 0);
            if (clone_1->DataLength())
            {
                ScrambleData(clone_1->Start(), clone_1->DataLength());
                NL_TEST_ASSERT(inSuite, memcmp(clone_1->Start(), payload_1, clone_1->DataLength()) != 0);
                NL_TEST_ASSERT(inSuite, 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());
                NL_TEST_ASSERT(inSuite, memcmp(clone_1_next->Start(), payload_2, clone_1_next->DataLength()) != 0);
                NL_TEST_ASSERT(inSuite, 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(PacketBuffer::kStructureSize + kOversizeDataSize));
    NL_TEST_ASSERT(inSuite, p != nullptr);

    p->next       = nullptr;
    p->payload    = reinterpret_cast<uint8_t *>(p) + PacketBuffer::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);
    NL_TEST_ASSERT(inSuite, handle->DataLength() == PacketBuffer::kMaxSizeWithoutReserve);

    PacketBufferHandle clone = handle.CloneData();
    NL_TEST_ASSERT(inSuite, !clone.IsNull());
    NL_TEST_ASSERT(inSuite, clone->DataLength() == PacketBuffer::kMaxSizeWithoutReserve);
    NL_TEST_ASSERT(inSuite, 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);
    NL_TEST_ASSERT(inSuite, handle->DataLength() == kOversizeDataSize);

    clone = handle.CloneData();
    NL_TEST_ASSERT(inSuite, 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
}

void PacketBufferTest::CheckPacketBufferWriter(nlTestSuite * inSuite, void * inContext)
{
    struct TestContext * const theContext = static_cast<struct TestContext *>(inContext);
    PacketBufferTest * const test         = theContext->test;
    NL_TEST_ASSERT(inSuite, test->mContext == theContext);

    const char kPayload[] = "Hello, world!";

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

    yay.Put(kPayload);
    yay.Put('\0');
    nay.Put(kPayload);
    nay.Put('\0');
    NL_TEST_ASSERT(inSuite, yay.Fit());
    NL_TEST_ASSERT(inSuite, !nay.Fit());

    PacketBufferHandle yayBuffer = yay.Finalize();
    PacketBufferHandle nayBuffer = nay.Finalize();
    NL_TEST_ASSERT(inSuite, yay.IsNull());
    NL_TEST_ASSERT(inSuite, nay.IsNull());
    NL_TEST_ASSERT(inSuite, !yayBuffer.IsNull());
    NL_TEST_ASSERT(inSuite, nayBuffer.IsNull());
    NL_TEST_ASSERT(inSuite, memcmp(yayBuffer->Start(), kPayload, sizeof kPayload) == 0);
}

/**
 *   Test Suite. It lists all the test functions.
 */
// clang-format off
const nlTest sTests[] =
{
    NL_TEST_DEF("PacketBuffer::New",                    PacketBufferTest::CheckNew),
    NL_TEST_DEF("PacketBuffer::Start",                  PacketBufferTest::CheckStart),
    NL_TEST_DEF("PacketBuffer::SetStart",               PacketBufferTest::CheckSetStart),
    NL_TEST_DEF("PacketBuffer::DataLength",             PacketBufferTest::CheckDataLength),
    NL_TEST_DEF("PacketBuffer::SetDataLength",          PacketBufferTest::CheckSetDataLength),
    NL_TEST_DEF("PacketBuffer::TotalLength",            PacketBufferTest::CheckTotalLength),
    NL_TEST_DEF("PacketBuffer::MaxDataLength",          PacketBufferTest::CheckMaxDataLength),
    NL_TEST_DEF("PacketBuffer::AvailableDataLength",    PacketBufferTest::CheckAvailableDataLength),
    NL_TEST_DEF("PacketBuffer::HasChainedBuffer",       PacketBufferTest::CheckHasChainedBuffer),
    NL_TEST_DEF("PacketBuffer::ReservedSize",           PacketBufferTest::CheckReservedSize),
    NL_TEST_DEF("PacketBuffer::AddToEnd",               PacketBufferTest::CheckAddToEnd),
    NL_TEST_DEF("PacketBuffer::PopHead",                PacketBufferTest::CheckPopHead),
    NL_TEST_DEF("PacketBuffer::CompactHead",            PacketBufferTest::CheckCompactHead),
    NL_TEST_DEF("PacketBuffer::ConsumeHead",            PacketBufferTest::CheckConsumeHead),
    NL_TEST_DEF("PacketBuffer::Consume",                PacketBufferTest::CheckConsume),
    NL_TEST_DEF("PacketBuffer::EnsureReservedSize",     PacketBufferTest::CheckEnsureReservedSize),
    NL_TEST_DEF("PacketBuffer::AlignPayload",           PacketBufferTest::CheckAlignPayload),
    NL_TEST_DEF("PacketBuffer::Next",                   PacketBufferTest::CheckNext),
    NL_TEST_DEF("PacketBuffer::Last",                   PacketBufferTest::CheckLast),
    NL_TEST_DEF("PacketBuffer::Read",                   PacketBufferTest::CheckRead),
    NL_TEST_DEF("PacketBuffer::AddRef",                 PacketBufferTest::CheckAddRef),
    NL_TEST_DEF("PacketBuffer::Free",                   PacketBufferTest::CheckFree),
    NL_TEST_DEF("PacketBuffer::FreeHead",               PacketBufferTest::CheckFreeHead),
    NL_TEST_DEF("PacketBuffer::HandleConstruct",        PacketBufferTest::CheckHandleConstruct),
    NL_TEST_DEF("PacketBuffer::HandleMove",             PacketBufferTest::CheckHandleMove),
    NL_TEST_DEF("PacketBuffer::HandleRelease",          PacketBufferTest::CheckHandleRelease),
    NL_TEST_DEF("PacketBuffer::HandleFree",             PacketBufferTest::CheckHandleFree),
    NL_TEST_DEF("PacketBuffer::HandleRetain",           PacketBufferTest::CheckHandleRetain),
    NL_TEST_DEF("PacketBuffer::HandleAdopt",            PacketBufferTest::CheckHandleAdopt),
    NL_TEST_DEF("PacketBuffer::HandleHold",             PacketBufferTest::CheckHandleHold),
    NL_TEST_DEF("PacketBuffer::HandleAdvance",          PacketBufferTest::CheckHandleAdvance),
    NL_TEST_DEF("PacketBuffer::HandleRightSize",        PacketBufferTest::CheckHandleRightSize),
    NL_TEST_DEF("PacketBuffer::HandleCloneData",        PacketBufferTest::CheckHandleCloneData),
    NL_TEST_DEF("PacketBuffer::PacketBufferWriter",     PacketBufferTest::CheckPacketBufferWriter),

    NL_TEST_SENTINEL()
};
// clang-format on

int TestSystemPacketBuffer()
{
    // clang-format off
    nlTestSuite theSuite = {
        .name ="chip-system-packetbuffer",
        .tests = &sTests[0],
        .setup = PacketBufferTest::TestSetup,
        .tear_down = PacketBufferTest::TestTeardown,
        // .initialize = PacketBufferTest::TestInitialize,
        .terminate = PacketBufferTest::TestTerminate
    };
    // clang-format on

    // Run test suit againt one context.
    nlTestRunner(&theSuite, &sContext);

    return (nlTestRunnerStats(&theSuite));
}

CHIP_REGISTER_TEST_SUITE(TestSystemPacketBuffer)
