/*
 *
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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>nl::Weave::System::PacketBuffer</tt>, a class that
 *      provides structure for network packet buffer management.
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include <SystemLayer/SystemPacketBuffer.h>

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
#include <lwip/tcpip.h>
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

#include <nlunit-test.h>

using ::nl::Weave::System::PacketBuffer;

#if !WEAVE_SYSTEM_CONFIG_USE_LWIP
using ::nl::Weave::System::pbuf;
#endif


// Test input vector format.


struct TestContext {
    uint16_t    init_len;
    uint16_t    reserved_size;
    uint8_t *   start_buffer;
    uint8_t *   end_buffer;
    uint8_t *   payload_ptr;
    struct pbuf *buf;
};


// Test input data.


static struct TestContext sContext[] = {
      { 0,      0,                               NULL, NULL, NULL, NULL },
      { 0,      10,                              NULL, NULL, NULL, NULL },
      { 0,      128,                             NULL, NULL, NULL, NULL },
      { 0,      1536,                            NULL, NULL, NULL, NULL },
      { 0,      WEAVE_SYSTEM_PACKETBUFFER_SIZE,  NULL, NULL, NULL, NULL }
};

static const uint16_t sLengths[] = { 0, 1, 10, 128, WEAVE_SYSTEM_PACKETBUFFER_SIZE, UINT16_MAX };

// Number of test context examples.
static const size_t kTestElements = sizeof(sContext) / sizeof(struct TestContext);
static const size_t kTestLengths = sizeof(sLengths) / sizeof(uint16_t);


// 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)))

/**
 *  Free allocated test buffer memory.
 */
static void BufferFree(struct TestContext* theContext)
{
    if (theContext->buf != NULL)
    {
        PacketBuffer::Free(OF_LWIP_PBUF(theContext->buf));
        theContext->buf = NULL;
    }
}

/**
 *  Allocate memory for a test buffer and configure according to test context.
 */
static void BufferAlloc(struct TestContext* theContext)
{
    const size_t lInitialSize = WEAVE_SYSTEM_PACKETBUFFER_HEADER_SIZE + theContext->reserved_size;
    const size_t lAllocSize = WEAVE_SYSTEM_PACKETBUFFER_SIZE;

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    u8_t lType, lFlags;
#if LWIP_PBUF_FROM_CUSTOM_POOLS
    u16_t lPool;
#endif // LWIP_PBUF_FROM_CUSTOM_POOLS
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

    if (theContext->buf == NULL)
    {
        theContext->buf = TO_LWIP_PBUF(PacketBuffer::New(0));
    }

    if (theContext->buf == NULL)
    {
        fprintf(stderr, "Failed to allocate %zuB memory: %s\n", lAllocSize, strerror(errno));
        exit(EXIT_FAILURE);
    }

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    lType = theContext->buf->type;
    lFlags = theContext->buf->flags;
#if LWIP_PBUF_FROM_CUSTOM_POOLS
    lPool = theContext->buf->pool;
#endif // LWIP_PBUF_FROM_CUSTOM_POOLS
    memset(theContext->buf, 0, lAllocSize);
    theContext->buf->type = lType;
    theContext->buf->flags = lFlags;
#if LWIP_PBUF_FROM_CUSTOM_POOLS
    theContext->buf->pool = lPool;
#endif // LWIP_PBUF_FROM_CUSTOM_POOLS
#else // !WEAVE_SYSTEM_CONFIG_USE_LWIP
    memset(theContext->buf, 0, lAllocSize);
#if WEAVE_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC == 0
    theContext->buf->alloc_size = lAllocSize;
#endif // WEAVE_SYSTEM_CONFIG_PACKETBUFFER_MAXALLOC == 0
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

    theContext->start_buffer = reinterpret_cast<uint8_t*>(theContext->buf);
    theContext->end_buffer = reinterpret_cast<uint8_t*>(theContext->buf) + lAllocSize;

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

/**
 *  Setup buffer layout as it is used by PacketBuffer class.
 */
static PacketBuffer* PrepareTestBuffer(struct TestContext* theContext)
{
    BufferAlloc(theContext);

    theContext->buf->next = NULL;
    theContext->buf->payload = theContext->payload_ptr;
    theContext->buf->ref = 1;
    theContext->buf->len = theContext->init_len;
    theContext->buf->tot_len = theContext->init_len;

    return reinterpret_cast<PacketBuffer*>(theContext->buf);
}
// Test functions invoked from the suite.


/**
 *  Test PacketBuffer::Start() function.
 */
static void CheckStart(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        PacketBuffer *buffer = PrepareTestBuffer(theContext);

        NL_TEST_ASSERT(inSuite, buffer->Start() == theContext->payload_ptr);

        theContext++;
    }
}

/**
 *  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.
 */
static void CheckSetStart(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);
    static const ptrdiff_t sSizePacketBuffer = WEAVE_SYSTEM_PACKETBUFFER_SIZE;

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        static const ptrdiff_t start_offset[] =
        {
            -sSizePacketBuffer,
            -128,
            -1,
            0,
            1,
            128,
            sSizePacketBuffer
        };

        for (size_t s = 0; s < sizeof(start_offset) / sizeof(start_offset[0]); s++)
        {
            PacketBuffer *buffer = PrepareTestBuffer(theContext);
            uint8_t *test_start = theContext->payload_ptr + start_offset[s];
            uint8_t *verify_start = test_start;

            buffer->SetStart(test_start);

            if (verify_start < theContext->start_buffer + WEAVE_SYSTEM_PACKETBUFFER_HEADER_SIZE)
            {
                // Set start before valid payload beginning.
                verify_start = theContext->start_buffer + WEAVE_SYSTEM_PACKETBUFFER_HEADER_SIZE;
            }

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

            NL_TEST_ASSERT(inSuite, theContext->buf->payload == verify_start);

            if ((verify_start - theContext->payload_ptr) > theContext->init_len)
            {
                // Set start to the beginning of payload, right after buffer's header.
                NL_TEST_ASSERT(inSuite, theContext->buf->len == 0);
            }
            else
            {
                // Set start to somewhere between the end of the buffer's
                // header and the end of payload.
                NL_TEST_ASSERT(inSuite, theContext->buf->len ==
                    (theContext->init_len -(verify_start - theContext->payload_ptr)));
            }
        }
        theContext++;
    }
}

/**
 *  Test PacketBuffer::DataLength() function.
 */
static void CheckDataLength(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        PacketBuffer *buffer = PrepareTestBuffer(theContext);

        NL_TEST_ASSERT(inSuite, buffer->DataLength() == theContext->buf->len);

        theContext++;
    }
}

/**
 *  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 lenghts were correctly adjusted.
 */
static void CheckSetDataLength(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theFirstContext = static_cast<struct TestContext *>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct TestContext *theSecondContext = static_cast<struct TestContext *>(inContext);

        for (size_t jth = 0; jth < kTestElements; jth++)
        {
            for (size_t n = 0; n < kTestLengths; n++)
            {
                PacketBuffer *buffer_1 = PrepareTestBuffer(theFirstContext);
                PacketBuffer *buffer_2 = PrepareTestBuffer(theSecondContext);

                if (theFirstContext == theSecondContext)
                {
                    // headOfChain (the second arg) is NULL
                    buffer_2->SetDataLength(sLengths[n], NULL);

                    if (sLengths[n] > (theSecondContext->end_buffer - theSecondContext->payload_ptr))
                    {
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->len ==
                            (theSecondContext->end_buffer - theSecondContext->payload_ptr));
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->tot_len ==
                            (theSecondContext->end_buffer - theSecondContext->payload_ptr));
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->next == NULL);
                    }
                    else
                    {
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->len == sLengths[n]);
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->tot_len == sLengths[n]);
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->next == NULL);
                    }
                }
                else
                {
                    // headOfChain (the second arg) is buffer_1
                    buffer_2->SetDataLength(sLengths[n], buffer_1);

                    if (sLengths[n] > (theSecondContext->end_buffer - theSecondContext->payload_ptr))
                    {
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->len ==
                            (theSecondContext->end_buffer - theSecondContext->payload_ptr));
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->tot_len ==
                            (theSecondContext->end_buffer - theSecondContext->payload_ptr));
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->next == NULL);

                        NL_TEST_ASSERT(inSuite, theFirstContext->buf->tot_len ==
                            (theFirstContext->init_len +
                            static_cast<int32_t>(theSecondContext->end_buffer - theSecondContext->payload_ptr) -
                            static_cast<int32_t>(theSecondContext->init_len)));
                    }
                    else
                    {
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->len == sLengths[n]);
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->tot_len == sLengths[n]);
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->next == NULL);

                        NL_TEST_ASSERT(inSuite, theFirstContext->buf->tot_len ==
                            (theFirstContext->init_len +
                            static_cast<int32_t>(sLengths[n]) -
                            static_cast<int32_t>(theSecondContext->init_len)));
                    }
                }
            }

            theSecondContext++;
        }

        theFirstContext++;
    }
}

/**
 *  Test PacketBuffer::TotalLength() function.
 */
static void CheckTotalLength(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        PacketBuffer *buffer = PrepareTestBuffer(theContext);

        NL_TEST_ASSERT(inSuite, buffer->TotalLength() == theContext->init_len);

        theContext++;
    }
}

/**
 *  Test PacketBuffer::MaxDataLength() function.
 */
static void CheckMaxDataLength(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        PacketBuffer *buffer = PrepareTestBuffer(theContext);

        NL_TEST_ASSERT(inSuite, buffer->MaxDataLength() ==
            (theContext->end_buffer - theContext->payload_ptr));

        theContext++;
    }
}

/**
 *  Test PacketBuffer::AvailableDataLength() function.
 */
static void CheckAvailableDataLength(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        PacketBuffer *buffer = PrepareTestBuffer(theContext);

        NL_TEST_ASSERT(inSuite, buffer->AvailableDataLength() ==
            ((theContext->end_buffer - theContext->payload_ptr) - theContext->init_len));

        theContext++;
    }
}

/**
 *  Test PacketBuffer::ReservedSize() function.
 */
static void CheckReservedSize(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        PacketBuffer& lBuffer = *PrepareTestBuffer(theContext);
        const size_t kAllocSize = lBuffer.AllocSize();

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

        theContext++;
    }
}

/**
 *  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.
 */
static void CheckAddToEnd(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theFirstContext = static_cast<struct TestContext *>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct TestContext *theSecondContext = static_cast<struct TestContext *>(inContext);

        for (size_t jth = 0; jth < kTestElements; jth++)
        {
            struct TestContext *theThirdContext = static_cast<struct TestContext *>(inContext);

            for (size_t kth = 0; kth < kTestElements; kth++)
            {
                PacketBuffer *buffer_1 = NULL;
                PacketBuffer *buffer_2 = NULL;
                PacketBuffer *buffer_3 = NULL;

                if (theFirstContext == theSecondContext ||
                    theFirstContext == theThirdContext ||
                    theSecondContext == theThirdContext)
                {
                    theThirdContext++;
                    continue;
                }

                buffer_1 = PrepareTestBuffer(theFirstContext);
                buffer_2 = PrepareTestBuffer(theSecondContext);
                buffer_3 = PrepareTestBuffer(theThirdContext);

                buffer_1->AddToEnd(buffer_2);

                NL_TEST_ASSERT(inSuite, theFirstContext->buf->tot_len ==
                    (theFirstContext->init_len + theSecondContext->init_len));
                NL_TEST_ASSERT(inSuite, theFirstContext->buf->next == theSecondContext->buf);
                NL_TEST_ASSERT(inSuite, theSecondContext->buf->next == NULL);

                NL_TEST_ASSERT(inSuite, theThirdContext->buf->next == NULL);

                buffer_1->AddToEnd(buffer_3);

                NL_TEST_ASSERT(inSuite, theFirstContext->buf->tot_len ==
                    (theFirstContext->init_len + theSecondContext->init_len + theThirdContext->init_len));
                NL_TEST_ASSERT(inSuite, theFirstContext->buf->next == theSecondContext->buf);
                NL_TEST_ASSERT(inSuite, theSecondContext->buf->next == theThirdContext->buf);
                NL_TEST_ASSERT(inSuite, theThirdContext->buf->next == NULL);

                theThirdContext++;
            }

            theSecondContext++;
        }

        theFirstContext++;
    }
}

/**
 *  Test PacketBuffer::DetachTail() 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 DetachTail()
 *               on the first buffer to unlink the second buffer. After the call,
 *               verify correct internal state of the first buffer.
 */
static void CheckDetachTail(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theFirstContext = static_cast<struct TestContext *>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct TestContext *theSecondContext = static_cast<struct TestContext *>(inContext);

        for (size_t jth = 0; jth < kTestElements; jth++)
        {
            PacketBuffer *buffer_1 = PrepareTestBuffer(theFirstContext);
            PacketBuffer *buffer_2 = PrepareTestBuffer(theSecondContext);
            PacketBuffer *returned = NULL;

            if (theFirstContext != theSecondContext)
            {
                theFirstContext->buf->next = theSecondContext->buf;
                theFirstContext->buf->tot_len += theSecondContext->init_len;
            }

            returned = buffer_1->DetachTail();

            NL_TEST_ASSERT(inSuite, theFirstContext->buf->next == NULL);
            NL_TEST_ASSERT(inSuite, theFirstContext->buf->tot_len == theFirstContext->init_len);

            if (theFirstContext != theSecondContext)
            {
                NL_TEST_ASSERT(inSuite, returned == buffer_2);
            }

            theSecondContext++;
        }

        theFirstContext++;
    }
}

/**
 *  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.
 */
static void CheckCompactHead(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theFirstContext = static_cast<struct TestContext *>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct TestContext *theSecondContext = static_cast<struct TestContext *>(inContext);

        for (size_t jth = 0; jth < kTestElements; jth++)
        {
            // start with various initial length for the first buffer
            for (size_t k = 0; k < kTestLengths; k++)
            {
                // start with various initial length for the second buffer
                for (size_t l = 0; l < kTestLengths; l++)
                {
                    PacketBuffer *buffer_1 = PrepareTestBuffer(theFirstContext);
                    PacketBuffer *buffer_2 = PrepareTestBuffer(theSecondContext);
                    uint16_t len1 = 0;
                    uint16_t len2 = 0;

                    buffer_1->SetDataLength(sLengths[k], buffer_1);
                    len1 = buffer_1->DataLength();

                    if (theFirstContext != theSecondContext)
                    {
                        theFirstContext->buf->next = theSecondContext->buf;

                        // Add various lengths to the second buffer
                        buffer_2->SetDataLength(sLengths[l], buffer_1);
                        len2 = buffer_2->DataLength();
                    }

                    buffer_1->CompactHead();

                    NL_TEST_ASSERT(inSuite, theFirstContext->buf->payload ==
                        (theFirstContext->start_buffer + WEAVE_SYSTEM_PACKETBUFFER_HEADER_SIZE));

                    /* verify length of the first buffer */
                    if (theFirstContext == theSecondContext) {
                        NL_TEST_ASSERT(inSuite, theFirstContext->buf->tot_len == len1);
                    }
                    else if (theFirstContext->buf->tot_len > buffer_1->MaxDataLength())
                    {
                        NL_TEST_ASSERT(inSuite, theFirstContext->buf->len == buffer_1->MaxDataLength());
                        NL_TEST_ASSERT(inSuite, theSecondContext->buf->len == theFirstContext->buf->tot_len -
                            buffer_1->MaxDataLength());
                    }
                    else
                    {
                        NL_TEST_ASSERT(inSuite, theFirstContext->buf->len == theFirstContext->buf->tot_len);
                        if (len1 >= buffer_1->MaxDataLength() && len2 == 0)
                        {
                            /* make sure the second buffer is not freed */
                            NL_TEST_ASSERT(inSuite, theFirstContext->buf->next == theSecondContext->buf);
                        }
                        else
                        {
                            /* make sure the second buffer is freed */
                            NL_TEST_ASSERT(inSuite, theFirstContext->buf->next == NULL);
                            theSecondContext->buf = NULL;
                        }
                    }
                }
            }
            theSecondContext++;
        }

        theFirstContext++;
    }
}

/**
 *  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.
 */
static void CheckConsumeHead(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        for (size_t n = 0; n < kTestLengths; n++)
        {
            PacketBuffer *buffer = PrepareTestBuffer(theContext);

            buffer->ConsumeHead(sLengths[n]);

            if (sLengths[n] > theContext->init_len)
            {
                NL_TEST_ASSERT(inSuite, theContext->buf->payload == (theContext->payload_ptr + theContext->init_len));
                NL_TEST_ASSERT(inSuite, theContext->buf->len == 0);
                NL_TEST_ASSERT(inSuite, theContext->buf->tot_len == 0);
            }
            else
            {
                NL_TEST_ASSERT(inSuite, theContext->buf->payload == (theContext->payload_ptr + sLengths[n]));
                NL_TEST_ASSERT(inSuite, theContext->buf->len == (theContext->buf->len - sLengths[n]));
                NL_TEST_ASSERT(inSuite, theContext->buf->tot_len == (theContext->buf->tot_len - sLengths[n]));
            }

            if (theContext->buf->ref == 0) {
                theContext->buf = NULL;
            }
        }

        theContext++;
    }
}

/**
 *  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.
 */
static void CheckConsume(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theFirstContext = static_cast<struct TestContext *>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct TestContext *theSecondContext = static_cast<struct TestContext *>(inContext);

        for (size_t jth = 0; jth < kTestElements; jth++)
        {
            // consume various amounts of memory
            for (size_t c = 0; c < kTestLengths; c++)
            {
                // start with various initial length for the first buffer
                for (size_t k = 0; k < kTestLengths; k++)
                {
                    // start with various initial length for the second buffer
                    for (size_t l = 0; l < kTestLengths; l++)
                    {
                        PacketBuffer *buffer_1;
                        PacketBuffer *buffer_2;
                        PacketBuffer *returned;
                        uint16_t buf_1_len = 0;
                        uint16_t buf_2_len = 0;

                        if (theFirstContext == theSecondContext)
                        {
                            continue;
                        }

                        buffer_1 = PrepareTestBuffer(theFirstContext);
                        buffer_2 = PrepareTestBuffer(theSecondContext);

                        theFirstContext->buf->next = theSecondContext->buf;

                        // Add various lengths to buffers
                        buffer_1->SetDataLength(sLengths[k], buffer_1);
                        buffer_2->SetDataLength(sLengths[l], buffer_1);

                        buf_1_len = theFirstContext->buf->len;
                        buf_2_len = theSecondContext->buf->len;

                        returned = buffer_1->Consume(sLengths[c]);

                        if (sLengths[c] == 0)
                        {
                            NL_TEST_ASSERT(inSuite, returned == buffer_1);
                            continue;
                        }

                        if (sLengths[c] < buf_1_len)
                        {
                            NL_TEST_ASSERT(inSuite, returned == buffer_1);
                        }
                        else if ((sLengths[c] >= buf_1_len) && (sLengths[c] < buf_1_len + buf_2_len ||
                              (sLengths[c] == buf_1_len + buf_2_len && buf_2_len == 0)))
                        {
                            NL_TEST_ASSERT(inSuite, returned == buffer_2);
                            theFirstContext->buf = NULL;
                        }
                        else if (sLengths[c] >= (buf_1_len + buf_2_len))
                        {
                            NL_TEST_ASSERT(inSuite, returned == NULL);
                            theFirstContext->buf = NULL;
                            theSecondContext->buf = NULL;
                        }
                    }
                }
            }

            theSecondContext++;
        }

        theFirstContext++;
    }
}

/**
 *  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.
 */
static void CheckEnsureReservedSize(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        for (size_t n = 0; n < kTestLengths; n++)
        {
            PacketBuffer& lBuffer = *PrepareTestBuffer(theContext);
            const size_t kAllocSize = lBuffer.AllocSize();
            uint16_t reserved_size = theContext->reserved_size;

            if (WEAVE_SYSTEM_PACKETBUFFER_HEADER_SIZE + theContext->reserved_size > kAllocSize)
            {
                reserved_size = kAllocSize - WEAVE_SYSTEM_PACKETBUFFER_HEADER_SIZE;
            }

            if (sLengths[n] <= reserved_size)
            {
                NL_TEST_ASSERT(inSuite, lBuffer.EnsureReservedSize(sLengths[n]) == true);
                continue;
            }

            if ((sLengths[n] + theContext->init_len) > (kAllocSize - WEAVE_SYSTEM_PACKETBUFFER_HEADER_SIZE))
            {
                NL_TEST_ASSERT(inSuite, lBuffer.EnsureReservedSize(sLengths[n]) == false);
                continue;
            }

            NL_TEST_ASSERT(inSuite, lBuffer.EnsureReservedSize(sLengths[n]) == true);
            NL_TEST_ASSERT(inSuite, theContext->buf->payload == (theContext->payload_ptr + sLengths[n] - reserved_size));
        }

        theContext++;
    }
}

/**
 *  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.
 */
static void CheckAlignPayload(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        for (size_t n = 0; n < kTestLengths - 1; n++)
        {
            PacketBuffer& lBuffer = *PrepareTestBuffer(theContext);
            const size_t kAllocSize = lBuffer.AllocSize();

            if (sLengths[n] == 0)
            {
                NL_TEST_ASSERT(inSuite, lBuffer.AlignPayload(sLengths[n]) == false);
                continue;
            }

            uint16_t reserved_size = theContext->reserved_size;
            if (theContext->reserved_size > kAllocSize)
            {
                reserved_size = kAllocSize;
            }

            uint16_t payload_offset = (unsigned long) lBuffer.Start() % sLengths[n];
            uint16_t payload_shift = 0;
            if (payload_offset > 0)
                payload_shift = sLengths[n] - payload_offset;

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

        theContext++;
    }
}

/**
 *  Test PacketBuffer::Next() function.
 */
static void CheckNext(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theFirstContext = static_cast<struct TestContext *>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct TestContext *theSecondContext = static_cast<struct TestContext *>(inContext);

        for (size_t jth = 0; jth < kTestElements; jth++)
        {
            PacketBuffer *buffer_1 = PrepareTestBuffer(theFirstContext);
            PacketBuffer *buffer_2 = PrepareTestBuffer(theSecondContext);

            if (theFirstContext != theSecondContext)
            {
                theFirstContext->buf->next = theSecondContext->buf;

                NL_TEST_ASSERT(inSuite, buffer_1->Next() == buffer_2);
            }
            else
            {
                NL_TEST_ASSERT(inSuite, buffer_1->Next() == NULL);
            }

            NL_TEST_ASSERT(inSuite, buffer_2->Next() == NULL);
            theSecondContext++;
        }

        theFirstContext++;
    }
}

/**
 *  Test PacketBuffer::AddRef() function.
 */
static void CheckAddRef(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        PacketBuffer *buffer = PrepareTestBuffer(theContext);
        buffer->AddRef();

        NL_TEST_ASSERT(inSuite, theContext->buf->ref == 2);

        theContext++;
    }
}

/**
 *  Test PacketBuffer::NewWithAvailableSize() and PacketBuffer::Free() functions.
 *
 *  Description: For every buffer-configuration from inContext, create a
 *               buffer's instance using NewWithAvailableSize() method. Then, verify that
 *               when the size of the reserved space passed to NewWithAvailableSize() is
 *               greater than #WEAVE_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX, the method
 *               returns NULL. Otherwise, check for correctness of initializing
 *               the new buffer's internal state. Finally, free the buffer.
 */
static void CheckNewWithAvailableSizeAndFree(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);
    PacketBuffer *buffer;

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct pbuf *pb = NULL;

        buffer = PacketBuffer::NewWithAvailableSize(theContext->reserved_size, 0);

        if (theContext->reserved_size > WEAVE_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX)
        {
            NL_TEST_ASSERT(inSuite, buffer == NULL);
            theContext++;
            continue;
        }

        NL_TEST_ASSERT(inSuite, theContext->reserved_size <= buffer->AllocSize());
        NL_TEST_ASSERT(inSuite, buffer != NULL);

        if (buffer != NULL)
        {
            pb = TO_LWIP_PBUF(buffer);

            NL_TEST_ASSERT(inSuite, pb->len == 0);
            NL_TEST_ASSERT(inSuite, pb->tot_len == 0);
            NL_TEST_ASSERT(inSuite, pb->next == NULL);
            NL_TEST_ASSERT(inSuite, pb->ref == 1);
        }

        PacketBuffer::Free(buffer);

        theContext++;
    }

    // Use the rest of the buffer space
    do
    {
        buffer = PacketBuffer::NewWithAvailableSize(0, 0);
    }
    while (buffer != NULL);
}

/**
 *  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.
 */
static void CheckFree(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theFirstContext = static_cast<struct TestContext *>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct TestContext *theSecondContext = static_cast<struct TestContext *>(inContext);

        for (size_t jth = 0; jth < kTestElements; jth++)
        {
            const uint16_t init_ref_count[] = { 1, 2, 3 };
            const int refs = sizeof(init_ref_count) / sizeof(uint16_t);

            // start with various buffer ref counts
            for (size_t r = 0; r < refs; r++)
            {
                PacketBuffer *buffer_1;

                if (theFirstContext == theSecondContext)
                {
                    continue;
                }

                buffer_1 = PrepareTestBuffer(theFirstContext);
                (void)PrepareTestBuffer(theSecondContext);

                theFirstContext->buf->next = theSecondContext->buf;

                // Add various buffer ref counts
                theFirstContext->buf->ref = init_ref_count[r];
                theSecondContext->buf->ref = init_ref_count[(r + 1) % refs];

                PacketBuffer::Free(buffer_1);

                NL_TEST_ASSERT(inSuite, theFirstContext->buf->ref == (init_ref_count[r] - 1));

                if (init_ref_count[r] == 1)
                {
                    NL_TEST_ASSERT(inSuite, theSecondContext->buf->ref == (init_ref_count[(r + 1) % refs] - 1));
                }
                else
                {
                    NL_TEST_ASSERT(inSuite, theSecondContext->buf->ref == (init_ref_count[(r + 1) % refs]));
                }

                if (init_ref_count[r] > 1)
                {
                    NL_TEST_ASSERT(inSuite, theFirstContext->buf->next == theSecondContext->buf);
                }

                if (theFirstContext->buf->ref == 0)
                {
                    theFirstContext->buf = NULL;
                }

                if (theSecondContext->buf->ref == 0)
                {
                    theSecondContext->buf = NULL;
                }
            }

            theSecondContext++;
        }

        theFirstContext++;
    }
}

/**
 *  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.
 */
static void CheckFreeHead(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theFirstContext = static_cast<struct TestContext *>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        struct TestContext *theSecondContext = static_cast<struct TestContext *>(inContext);

        for (size_t jth = 0; jth < kTestElements; jth++)
        {
            PacketBuffer *buffer_1;
            PacketBuffer *buffer_2;
            PacketBuffer *returned = NULL;

            if (theFirstContext == theSecondContext)
            {
                continue;
            }

            buffer_1 = PrepareTestBuffer(theFirstContext);
            buffer_2 = PrepareTestBuffer(theSecondContext);

            theFirstContext->buf->next = theSecondContext->buf;

            returned = PacketBuffer::FreeHead(buffer_1);

            NL_TEST_ASSERT(inSuite, returned == buffer_2);

            theFirstContext->buf = NULL;
            theSecondContext++;
        }

        theFirstContext++;
    }
}

/**
 *  Test PacketBuffer::BuildFreeList() function.
 */
static void CheckBuildFreeList(nlTestSuite *inSuite, void *inContext)
{
    // BuildFreeList() is a private method called automatically.
    (void)inSuite;
    (void)inContext;
}

/**
 *   Test Suite. It lists all the test functions.
 */
static const nlTest sTests[] = {
    NL_TEST_DEF("PacketBuffer::NewWithAvailableSize&PacketBuffer::Free", CheckNewWithAvailableSizeAndFree),
    NL_TEST_DEF("PacketBuffer::Start",                          CheckStart),
    NL_TEST_DEF("PacketBuffer::SetStart",                       CheckSetStart),
    NL_TEST_DEF("PacketBuffer::DataLength",                     CheckDataLength),
    NL_TEST_DEF("PacketBuffer::SetDataLength",                  CheckSetDataLength),
    NL_TEST_DEF("PacketBuffer::TotalLength",                    CheckTotalLength),
    NL_TEST_DEF("PacketBuffer::MaxDataLength",                  CheckMaxDataLength),
    NL_TEST_DEF("PacketBuffer::AvailableDataLength",            CheckAvailableDataLength),
    NL_TEST_DEF("PacketBuffer::ReservedSize",                   CheckReservedSize),
    NL_TEST_DEF("PacketBuffer::AddToEnd",                       CheckAddToEnd),
    NL_TEST_DEF("PacketBuffer::DetachTail",                     CheckDetachTail),
    NL_TEST_DEF("PacketBuffer::CompactHead",                    CheckCompactHead),
    NL_TEST_DEF("PacketBuffer::ConsumeHead",                    CheckConsumeHead),
    NL_TEST_DEF("PacketBuffer::Consume",                        CheckConsume),
    NL_TEST_DEF("PacketBuffer::EnsureReservedSize",             CheckEnsureReservedSize),
    NL_TEST_DEF("PacketBuffer::AlignPayload",                   CheckAlignPayload),
    NL_TEST_DEF("PacketBuffer::Next",                           CheckNext),
    NL_TEST_DEF("PacketBuffer::AddRef",                         CheckAddRef),
    NL_TEST_DEF("PacketBuffer::Free",                           CheckFree),
    NL_TEST_DEF("PacketBuffer::FreeHead",                       CheckFreeHead),
    NL_TEST_DEF("PacketBuffer::BuildFreeList",                  CheckBuildFreeList),

    NL_TEST_SENTINEL()
};

/**
 * Set up the test suite.
 *
 *  This is a work-around to initiate PacketBuffer protected class instance's data and set it to a known state, before an instance
 *  is created.
 */
static int TestSetup(void *inContext)
{
    struct TestContext* theContext = reinterpret_cast<TestContext*>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        BufferAlloc(theContext);
        theContext++;
    }

    return (SUCCESS);
}

/**
 * Tear down the test suite.
 *
 *  Free memory reserved at TestSetup.
 */
static int TestTeardown(void *inContext)
{
    struct TestContext* theContext = reinterpret_cast<TestContext*>(inContext);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        BufferFree(theContext);
        theContext++;
    }

    return (SUCCESS);
}

int main(void)
{
    nlTestSuite theSuite = {
        "weave-system-packetbuffer",
        &sTests[0],
        TestSetup,
        TestTeardown
    };

#if WEAVE_SYSTEM_CONFIG_USE_LWIP
    tcpip_init(NULL, NULL);
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

    // Generate machine-readable, comma-separated value (CSV) output.
    nl_test_set_output_style(OUTPUT_CSV);

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

    return nlTestRunnerStats(&theSuite);
}
