/*
 *
 *    Copyright (c) 2015-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::Inet::InetBuffer</tt>,
 *     a class that provides structure for network buffer management.
 *
 */

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include <stdint.h>

#include <InetLayer/InetConfig.h>

#if INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

#include <string.h>

#include <InetLayer/InetBuffer.h>

#include <nltest.h>

#include "ToolCommon.h"

#define MEM_ALIGN_SIZE(SZ, ALIGN)       (((SZ) + (ALIGN) - 1) & ~((ALIGN) - 1))
#if INET_LWIP
#define INET_BUF_SIZE                   LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE)
#define INET_BUF_HEADER_SIZE            LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf))
#else
#define INET_BUF_SIZE                   WEAVE_SYSTEM_PACKETBUFFER_SIZE
#define INET_BUF_HEADER_SIZE            MEM_ALIGN_SIZE(sizeof(InetBuffer), 4)
#endif

#define INET_TO_PBUF(x)                 (static_cast<struct pbuf*>(static_cast<void *>(x)))
#define PBUF_TO_INET(x)                 (static_cast<InetBuffer*>(static_cast<void *>(x)))

using namespace nl::Inet;


// 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,      WEAVE_SYSTEM_PACKETBUFFER_SIZE,             NULL, NULL, NULL, NULL },
      { 0,      INET_BUF_SIZE,                              NULL, NULL, NULL, NULL }
};

static const uint16_t sLengths[] = { 0, 1, 10, 128, INET_BUF_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.


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

/**
 *  Allocate memory for a test buffer and configure according to test context.
 */
static void BufferAlloc(struct TestContext *theContext)
{
    if (theContext->buf == NULL)
    {
        theContext->buf = INET_TO_PBUF(InetBuffer::New(0));
    }

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

    memset(theContext->buf, 0, INET_BUF_SIZE);

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

    if (INET_BUF_HEADER_SIZE + theContext->reserved_size > INET_BUF_SIZE)
    {
        theContext->payload_ptr = (theContext->start_buffer + INET_BUF_SIZE);
    }
    else
    {
        theContext->payload_ptr = (theContext->start_buffer + INET_BUF_HEADER_SIZE + theContext->reserved_size);
    }
}

/**
 *  Setup buffer layout as it is used by InetBuffer class.
 */
static InetBuffer *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;
#if INET_LWIP
    theContext->buf->type = PBUF_POOL;
#endif

    return reinterpret_cast<InetBuffer*>(theContext->buf);
}


// Test functions invoked from the suite.


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

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

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

        theContext++;
    }
}

/**
 *  Test InetBuffer::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);

    for (size_t ith = 0; ith < kTestElements; ith++)
    {
        const int start_offset[] = { -static_cast<int>(INET_BUF_SIZE), -128, -1, 0, 1, 128, static_cast<int>(INET_BUF_SIZE) };

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

            buffer->SetStart(test_start);

            if (verify_start <= theContext->start_buffer + INET_BUF_HEADER_SIZE)
            {
                // Set start before valid payload beginning.
                verify_start = theContext->start_buffer + INET_BUF_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 InetBuffer::DataLength() function.
 */
static void CheckDataLength(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

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

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

        theContext++;
    }
}

/**
 *  Test InetBuffer::SetDataLength() function.
 *
 *  Description: Take two initial configurations of InetBuffer from
 *               inContext and create two InetBuffer 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++)
            {
                InetBuffer *buffer_1 = PrepareTestBuffer(theFirstContext);
                InetBuffer *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 InetBuffer::TotalLength() function.
 */
static void CheckTotalLength(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

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

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

        theContext++;
    }
}

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

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

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

        theContext++;
    }
}

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

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

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

        theContext++;
    }
}

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

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

        if (INET_BUF_HEADER_SIZE + theContext->reserved_size > INET_BUF_SIZE)
        {
            NL_TEST_ASSERT(inSuite, buffer->ReservedSize() ==
                (INET_BUF_SIZE - INET_BUF_HEADER_SIZE));
        }
        else
        {
            NL_TEST_ASSERT(inSuite, buffer->ReservedSize() ==
                theContext->reserved_size);
        }

        theContext++;
    }
}

/**
 *  Test InetBuffer::AddToEnd() function.
 *
 *  Description: Take three initial configurations of InetBuffer from
 *               inContext, create three InetBuffers based on those
 *               configurations and then link those buffers together with
 *               InetBuffer: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++)
            {
                InetBuffer *buffer_1 = NULL;
                InetBuffer *buffer_2 = NULL;
                InetBuffer *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 InetBuffer::DetachTail() function.
 *
 *  Description: Take two initial configurations of InetBuffer from
 *               inContext and create two InetBuffer 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++)
        {
            InetBuffer *buffer_1 = PrepareTestBuffer(theFirstContext);
            InetBuffer *buffer_2 = PrepareTestBuffer(theSecondContext);
            InetBuffer *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 InetBuffer::CompactHead() function.
 *
 *  Description: Take two initial configurations of InetBuffer from
 *               inContext and create two InetBuffer 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++)
                {
                    InetBuffer *buffer_1 = PrepareTestBuffer(theFirstContext);
                    InetBuffer *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 + INET_BUF_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 InetBuffer::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++)
        {
            InetBuffer *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 InetBuffer::Consume() function.
 *
 *  Description: Take two different initial configurations of InetBuffer from
 *               inContext and create two InetBuffer 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++)
                    {
                        InetBuffer *buffer_1;
                        InetBuffer *buffer_2;
                        InetBuffer *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 InetBuffer::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++)
        {
            InetBuffer *buffer = PrepareTestBuffer(theContext);
            uint16_t reserved_size = theContext->reserved_size;

            if (INET_BUF_HEADER_SIZE + theContext->reserved_size > INET_BUF_SIZE)
            {
                reserved_size = INET_BUF_SIZE - INET_BUF_HEADER_SIZE;
            }

            if (sLengths[n] <= reserved_size)
            {
                NL_TEST_ASSERT(inSuite, buffer->EnsureReservedSize(sLengths[n]) == true);
                continue;
            }

            if ((sLengths[n] + theContext->init_len) > (INET_BUF_SIZE - INET_BUF_HEADER_SIZE))
            {
                NL_TEST_ASSERT(inSuite, buffer->EnsureReservedSize(sLengths[n]) == false);
                continue;
            }

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

        theContext++;
    }
}

/**
 *  Test InetBuffer::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++)
        {
            InetBuffer *buffer = PrepareTestBuffer(theContext);

            if (sLengths[n] == 0)
            {
                NL_TEST_ASSERT(inSuite, buffer->AlignPayload(sLengths[n]) == false);
                continue;
            }

            uint16_t reserved_size = theContext->reserved_size;
            if (INET_BUF_HEADER_SIZE + theContext->reserved_size > INET_BUF_SIZE)
            {
                reserved_size = INET_BUF_SIZE - INET_BUF_HEADER_SIZE;
            }

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

            if (payload_shift <= INET_BUF_SIZE - INET_BUF_HEADER_SIZE - reserved_size)
            {
                NL_TEST_ASSERT(inSuite, buffer->AlignPayload(sLengths[n]) == true);
                NL_TEST_ASSERT(inSuite, ((unsigned long) buffer->Start() % sLengths[n]) == 0);
            }
            else
            {
                NL_TEST_ASSERT(inSuite, buffer->AlignPayload(sLengths[n]) == false);
            }
        }

        theContext++;
    }
}

/**
 *  Test InetBuffer::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++)
        {
            InetBuffer *buffer_1 = PrepareTestBuffer(theFirstContext);
            InetBuffer *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 InetBuffer::AddRef() function.
 */
static void CheckAddRef(nlTestSuite *inSuite, void *inContext)
{
    struct TestContext *theContext = (struct TestContext *)(inContext);

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

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

        theContext++;
    }
}

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

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

        buffer = InetBuffer::New(theContext->reserved_size);

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

        NL_TEST_ASSERT(inSuite, buffer != NULL);

        if (buffer != NULL)
        {
            pb = INET_TO_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);
        }

        InetBuffer::Free(buffer);

        theContext++;
    }

    // Use the rest of the buffer space
    do
    {
        buffer = InetBuffer::New();
    }
    while (buffer != NULL);
}

/**
 *  Test InetBuffer::Free() function.
 *
 *  Description: Take two different initial configurations of InetBuffer from
 *               inContext and create two InetBuffer 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++)
            {
                InetBuffer *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];

                InetBuffer::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 InetBuffer::FreeHead() function.
 *
 *  Description: Take two different initial configurations of InetBuffer from
 *               inContext and create two InetBuffer 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++)
        {
            InetBuffer *buffer_1;
            InetBuffer *buffer_2;
            InetBuffer *returned = NULL;

            if (theFirstContext == theSecondContext)
            {
                continue;
            }

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

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

            returned = InetBuffer::FreeHead(buffer_1);

            NL_TEST_ASSERT(inSuite, returned == buffer_2);

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

        theFirstContext++;
    }
}

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


// Test Suite


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

/**
 *  Set up the test suite.
 *  This is a work-around to initiate InetBuffer 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 = (struct 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 = (struct TestContext *)(inContext);

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

        theContext++;
    }

    return (SUCCESS);
}

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

    // Init lwip
#if INET_LWIP
    tcpip_init(NULL, NULL);
#endif

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

#else // !INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES

int main(void)
{
    return 0;
}

#endif // !INET_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES
