/*
 *
 *    Copyright (c) 2020-2021 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 defines the chip::System::PacketBuffer class,
 *      which provides the mechanisms for manipulating packets of *
 *      octet-serialized data.
 */

#pragma once

// Include configuration header
#include <system/SystemPacketBufferInternal.h>

// Include dependent headers
#include <lib/support/BufferWriter.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/DLLUtil.h>
#include <system/SystemAlignSize.h>
#include <system/SystemError.h>

#include <stddef.h>
#include <utility>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/mem.h>
#include <lwip/memp.h>
#include <lwip/pbuf.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

class PacketBufferTest;

namespace chip {
namespace System {

class PacketBufferHandle;

#if !CHIP_SYSTEM_CONFIG_USE_LWIP
struct pbuf
{
    struct pbuf * next;
    void * payload;
    uint16_t tot_len;
    uint16_t len;
    uint16_t ref;
#if CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP
    uint16_t alloc_size;
#endif
};
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP

/**    @class PacketBuffer
 *
 *     @brief
 *      The packet buffer class is the core structure used for manipulating packets of octet-serialized data, usually in the
 *      context of a data communications network, like Bluetooth or the Internet protocol.
 *
 *      In LwIP-based environments, this class is built on top of the pbuf structure defined in that library. In the absence of
 *      LwIP, chip provides either a malloc-based implementation, or a pool-based implementation that closely approximates the
 *      memory challenges of deeply embedded devices.
 *
 *      The PacketBuffer class, like many similar structures used in layered network stacks, provide a mechanism to reserve space
 *      for protocol headers at each layer of a configurable communication stack.  For details, see `PacketBufferHandle::New()`
 *      as well as LwIP documentation.
 *
 *      PacketBuffer objects are reference-counted, and normally held and used through a PacketBufferHandle that owns one of the
 *      counted references. When a PacketBufferHandle goes out of scope, its reference is released. To take ownership, a function
 *      takes a PacketBufferHandle by value. To borrow ownership, a function takes a `const PacketBufferHandle &`.
 *
 *      New objects of PacketBuffer class are initialized at the beginning of an allocation of memory obtained from the underlying
 *      environment, e.g. from LwIP pbuf target pools, from the standard C library heap, from an internal buffer pool. In the
 *      simple pool case, the size of the data buffer is PacketBuffer::kBlockSize.
 *
 *      PacketBuffer objects may be chained to accommodate larger payloads.  Chaining, however, is not transparent, and users of the
 *      class must explicitly decide to support chaining.  Examples of classes written with chaining support are as follows:
 *
 *          @ref chip::TLVReader
 *          @ref chip::TLVWriter
 *
 * ### PacketBuffer format
 *
 * <pre>
 *           ┌────────────────────────────────────┐
 *           │       ┌────────────────────┐       │
 *           │       │                    │◁──────┴───────▷│
 *  ┏━━━━━━━━┿━━━━━━━┿━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┓
 *  ┃ pbuf len payload ┃ reserve          ┃ data           ┃ unused                  ┃
 *  ┗━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━┛
 *  │                  │← ReservedSize() →│← DataLength() →│← AvailableDataLength() →│
 *  │                  │                  │← MaxDataLength() → · · · · · · · · · · ·→│
 *  │                  │                  Start()                                    │
 *  │← kStructureSize →│← AllocSize() → · · · · · · · · · · · · · · · · · · · · · · →│
 * </pre>
 *
 */
class DLL_EXPORT PacketBuffer : private pbuf
{
private:
    // The effective size of the packet buffer structure.
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    static constexpr uint16_t kStructureSize = LWIP_MEM_ALIGN_SIZE(sizeof(struct ::pbuf));
#else  // CHIP_SYSTEM_CONFIG_USE_LWIP
    static constexpr uint16_t kStructureSize         = CHIP_SYSTEM_ALIGN_SIZE(sizeof(::chip::System::pbuf), 4u);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

public:
    /**
     * The maximum size buffer an application can allocate with no protocol header reserve.
     */
#if CHIP_SYSTEM_PACKETBUFFER_FROM_LWIP_POOL
    static constexpr uint16_t kMaxSizeWithoutReserve = LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE);
#else
    static constexpr uint16_t kMaxSizeWithoutReserve = CHIP_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX;
#endif

    /**
     * The number of bytes to reserve in a network packet buffer to contain all the possible protocol encapsulation headers
     * before the application data.
     */
    static constexpr uint16_t kDefaultHeaderReserve = CHIP_SYSTEM_CONFIG_HEADER_RESERVE_SIZE;

    /**
     * The maximum size buffer an application can allocate with the default protocol header reserve.
     */
    static constexpr uint16_t kMaxSize = kMaxSizeWithoutReserve - kDefaultHeaderReserve;

    /**
     * Return the size of the allocation including the reserved and payload data spaces but not including space
     * allocated for the PacketBuffer structure.
     *
     *  @note    The allocation size is equal to or greater than the \c aAllocSize parameter to the \c Create method).
     *
     *  @return     size of the allocation
     */
    uint16_t AllocSize() const
    {
#if CHIP_SYSTEM_PACKETBUFFER_FROM_LWIP_STANDARD_POOL || CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL
        return kMaxSizeWithoutReserve;
#elif CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP
        return this->alloc_size;
#elif CHIP_SYSTEM_PACKETBUFFER_FROM_LWIP_CUSTOM_POOL
        // Temporary workaround for custom pbufs by assuming size to be PBUF_POOL_BUFSIZE
        if (this->flags & PBUF_FLAG_IS_CUSTOM)
            return LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) - kStructureSize;
        else
            return LWIP_MEM_ALIGN_SIZE(memp_sizes[this->pool]) - kStructureSize;
#else
#error "Unimplemented PacketBuffer storage case"
#endif
    }

    /**
     * Get a pointer to the start of data in a buffer.
     *
     *  @return pointer to the start of data.
     */
    uint8_t * Start() const { return static_cast<uint8_t *>(this->payload); }

    /**
     *  Set the the start of data in a buffer, adjusting length and total length accordingly.
     *
     *  @note The data within the buffer is not moved, only accounting information is changed.  The function is commonly used to
     *      either strip or prepend protocol headers in a zero-copy way.
     *
     *  @note This call should not be used on any buffer that is not the head of a buffer chain, as it only alters the current
     *      buffer.
     *
     *  @param[in] aNewStart - A pointer to where the new payload should start.  newStart will be adjusted internally to fall within
     *      the boundaries of the first buffer in the PacketBuffer chain.
     */
    void SetStart(uint8_t * aNewStart);

    /**
     * Get the length, in bytes, of data in a packet buffer.
     *
     *  @return length, in bytes (current payload length).
     */
    uint16_t DataLength() const { return this->len; }

    /**
     * Set the length, in bytes, of data in a packet buffer, adjusting total length accordingly.
     *
     *  The function sets the length, in bytes, of the data in the buffer, adjusting the total length appropriately. When the buffer
     *  is not the head of the buffer chain (common case: the caller adds data to the last buffer in the PacketBuffer chain prior to
     *  calling higher layers), the aChainHead __must__ be passed in to properly adjust the total lengths of each buffer ahead of
     *  the current buffer.
     *
     *  @param[in] aNewLen - new length, in bytes, of this buffer.
     *
     *  @param[in,out] aChainHead - the head of the buffer chain the current buffer belongs to.  May be \c nullptr if the current
     *      buffer is the head of the buffer chain.
     */
    void SetDataLength(uint16_t aNewLen, const PacketBufferHandle & aChainHead);
    void SetDataLength(uint16_t aNewLen) { SetDataLength(aNewLen, nullptr); }

    /**
     * Get the total length of packet data in the buffer chain.
     *
     *  @return total length, in octets.
     */
    uint16_t TotalLength() const { return this->tot_len; }

    /**
     * Get the maximum amount, in bytes, of data that will fit in the buffer given the current start position and buffer size.
     *
     *  @return number of bytes that fits in the buffer given the current start position.
     */
    uint16_t MaxDataLength() const;

    /**
     * Get the number of bytes of data that can be added to the current buffer given the current start position and data length.
     *
     *  @return the length, in bytes, of data that will fit in the current buffer given the current start position and data length.
     */
    uint16_t AvailableDataLength() const;

    /**
     * Get the number of bytes within the current buffer between the start of the buffer and the current data start position.
     *
     *  @return the amount, in bytes, of space between the start of the buffer and the current data start position.
     */
    uint16_t ReservedSize() const;

    /**
     * Determine whether there are any additional buffers chained to the current buffer.
     *
     *  @return \c true if there is a chained buffer.
     */
    bool HasChainedBuffer() const { return ChainedBuffer() != nullptr; }

    /**
     * Add the given packet buffer to the end of the buffer chain, adjusting the total length of each buffer in the chain
     * accordingly.
     *
     *  @note The current packet buffer must be the head of the buffer chain for the lengths to be adjusted properly.
     *
     *  @note Ownership is transferred from the argument to the `next` link at the end of the current chain.
     *
     *  @param[in] aPacket - the packet buffer to be added to the end of the current chain.
     */
    void AddToEnd(PacketBufferHandle && aPacket);

    /**
     * Move data from subsequent buffers in the chain into the current buffer until it is full.
     *
     *  Only the current buffer is compacted: the data within the current buffer is moved to the front of the buffer, eliminating
     *  any reserved space. The remaining available space is filled with data moved from subsequent buffers in the chain, until the
     *  current buffer is full. If a subsequent buffer in the chain is moved into the current buffer in its entirety, it is removed
     *  from the chain and freed. The method takes no parameters, returns no results and cannot fail.
     */
    void CompactHead();

    /**
     * Adjust the current buffer to indicate the amount of data consumed.
     *
     *  Advance the data start position in the current buffer by the specified amount, in bytes, up to the length of data in the
     *  buffer. Decrease the length and total length by the amount consumed.
     *
     *  @param[in] aConsumeLength - number of bytes to consume from the current buffer.
     */
    void ConsumeHead(uint16_t aConsumeLength);

    /**
     * Ensure the buffer has at least the specified amount of reserved space.
     *
     *  Ensure the buffer has at least the specified amount of reserved space, moving the data in the buffer forward to make room if
     *  necessary.
     *
     *  @param[in] aReservedSize - number of bytes desired for the headers.
     *
     *  @return \c true if the requested reserved size is available, \c false if there's not enough room in the buffer.
     */
    CHECK_RETURN_VALUE bool EnsureReservedSize(uint16_t aReservedSize);

    /**
     * Align the buffer payload on the specified bytes boundary.
     *
     *  Moving the payload in the buffer forward if necessary.
     *
     *  @param[in] aAlignBytes - specifies number of bytes alignment for the payload start pointer.
     *
     *  @return \c true if alignment is successful, \c false if there's not enough room in the buffer.
     */
    bool AlignPayload(uint16_t aAlignBytes);

    /**
     * Return the next buffer in a buffer chain.
     *
     *  If there is no next buffer, the handle will have \c IsNull() \c true.
     *
     *  @return a handle to the next buffer in the buffer chain.
     */
    CHECK_RETURN_VALUE PacketBufferHandle Next();

    /**
     * Return the last buffer in a buffer chain.
     *
     *  @return a handle to the last buffer in the buffer chain.
     */
    CHECK_RETURN_VALUE PacketBufferHandle Last();

    /**
     * Copies data from the payloads of a chain of packet buffers until a given amount of data has been copied.
     *
     * @param[in]  buf             Destination buffer; must be at least @a length bytes.
     * @param[in]  length          Destination buffer length.
     *
     * @retval #CHIP_ERROR_BUFFER_TOO_SMALL If the total length of the payloads in the chain is less than the requested @a length.
     * @retval #CHIP_ERROR_INTERNAL         In case of an inconsistency in the buffer chain.
     * @retval #CHIP_NO_ERROR               If the requested payload has been copied.
     */
    CHIP_ERROR Read(uint8_t * buf, size_t length) const;
    template <size_t N>
    inline CHIP_ERROR Read(uint8_t (&buf)[N]) const
    {
        return Read(buf, N);
    }

    /**
     * Perform an implementation-defined check on the validity of a PacketBuffer pointer.
     *
     * Unless enabled by #CHIP_CONFIG_MEMORY_DEBUG_CHECKS == 1, this function does nothing.
     *
     * When enabled, it performs an implementation- and configuration-defined check on
     * the validity of the packet buffer. It MAY log an error and/or abort the program
     * if the packet buffer or the implementation-defined memory management system is in
     * a faulty state. (Some configurations may not actually perform any check.)
     *
     * @note  A null pointer is not considered faulty.
     *
     *  @param[in] buffer - the packet buffer to check.
     */
    static void Check(const PacketBuffer * buffer)
    {
#if CHIP_SYSTEM_PACKETBUFFER_HAS_CHECK
        InternalCheck(buffer);
#endif
    }

private:
    // Memory required for a maximum-size PacketBuffer.
    static constexpr uint16_t kBlockSize = PacketBuffer::kStructureSize + PacketBuffer::kMaxSizeWithoutReserve;

    // Note: this condition includes DOXYGEN to work around a Doxygen error. DOXYGEN is never defined in any actual build.
#if CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL || defined(DOXYGEN)
    typedef union
    {
        pbuf Header;
        uint8_t Block[PacketBuffer::kBlockSize];
    } BufferPoolElement;
    static BufferPoolElement sBufferPool[CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE];
    static PacketBuffer * sFreeList;
    static PacketBuffer * BuildFreeList();
#endif // CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL || defined(DOXYGEN)

#if CHIP_SYSTEM_PACKETBUFFER_HAS_CHECK
    static void InternalCheck(const PacketBuffer * buffer);
#endif

    void AddRef();
    bool HasSoleOwnership() const { return (this->ref == 1); }
    static void Free(PacketBuffer * aPacket);
    static PacketBuffer * FreeHead(PacketBuffer * aPacket);

    PacketBuffer * ChainedBuffer() const { return static_cast<PacketBuffer *>(this->next); }
    PacketBuffer * Consume(uint16_t aConsumeLength);
    void Clear();
    void SetDataLength(uint16_t aNewLen, PacketBuffer * aChainHead);

    /**
     * Get a pointer to the start of the reserved space (which comes before the
     * payload).  The actual reserved space is the ReservedSize() bytes starting
     * at this pointer.
     */
    uint8_t * ReserveStart();
    const uint8_t * ReserveStart() const;

    friend class PacketBufferHandle;
    friend class ::PacketBufferTest;
};

static_assert(sizeof(pbuf) == sizeof(PacketBuffer), "PacketBuffer must not have additional members");

/**
 * @class PacketBufferHandle
 *
 * @brief
 *  Tracks ownership of a PacketBuffer.
 *
 *  PacketBuffer objects are reference-counted, and normally held and used through a PacketBufferHandle that owns one of the
 *  counted references. When a PacketBufferHandle goes out of scope, its reference is released. To take ownership, a function
 *  takes a PacketBufferHandle by value. To borrow ownership, a function takes a `const PacketBufferHandle &`.
 */
class DLL_EXPORT PacketBufferHandle
{
public:
    /**
     * Construct an empty PacketBufferHandle.
     */
    PacketBufferHandle() : mBuffer(nullptr) {}
    PacketBufferHandle(decltype(nullptr)) : mBuffer(nullptr) {}

    /**
     * Construct a PacketBufferHandle that takes ownership of a PacketBuffer from another.
     */
    PacketBufferHandle(PacketBufferHandle && aOther)
    {
        mBuffer        = aOther.mBuffer;
        aOther.mBuffer = nullptr;
    }

    ~PacketBufferHandle() { *this = nullptr; }

    /**
     * Take ownership of a PacketBuffer from another PacketBufferHandle, freeing any existing owned buffer.
     */
    PacketBufferHandle & operator=(PacketBufferHandle && aOther)
    {
        if (mBuffer != nullptr)
        {
            PacketBuffer::Free(mBuffer);
        }
        mBuffer        = aOther.mBuffer;
        aOther.mBuffer = nullptr;
        return *this;
    }

    /**
     * Free any buffer owned by this handle.
     */
    PacketBufferHandle & operator=(decltype(nullptr))
    {
        if (mBuffer != nullptr)
        {
            PacketBuffer::Free(mBuffer);
        }
        mBuffer = nullptr;
        return *this;
    }

    /**
     * Get a new handle to an existing buffer.
     *
     * @return a PacketBufferHandle that shares ownership with this.
     */
    PacketBufferHandle Retain() const
    {
        mBuffer->AddRef();
        return PacketBufferHandle(mBuffer);
    }

    /**
     * Access a PackerBuffer's public methods.
     */
    PacketBuffer * operator->() const { return mBuffer; }

    /**
     * Test whether this PacketBufferHandle is empty, or conversely owns a PacketBuffer.
     *
     * @return \c true if this PacketBufferHandle is empty; return \c false if it owns a PacketBuffer.
     */
    bool IsNull() const { return mBuffer == nullptr; }

    /**
     * Test whether the PacketBuffer owned by this PacketBufferHandle has unique ownership.
     *
     * @return \c true if the PacketBuffer owned by this PacketBufferHandle is solely owned; return \c false if
     * it has more than one ownership.
     */
    bool HasSoleOwnership() const { return mBuffer->HasSoleOwnership(); }

    /**
     *  Detach and return the head of a buffer chain while updating this handle to point to the remaining buffers.
     *  The current buffer must be the head of the chain.
     *
     *  This PacketBufferHandle now holds the ownership formerly held by the head of the chain.
     *  The returned PacketBufferHandle holds the ownership formerly held by this.
     *
     *  @return the detached buffer formerly at the head of the buffer chain.
     */
    CHECK_RETURN_VALUE PacketBufferHandle PopHead();

    /**
     * Free the first buffer in a chain.
     *
     *  @note When the buffer chain is referenced by multiple handles, `FreeHead()` will detach the head, but will not forcibly
     *  deallocate the head buffer.
     */
    void FreeHead()
    {
        // `PacketBuffer::FreeHead()` frees the current head; this takes ownership from the `next` link.
        mBuffer = PacketBuffer::FreeHead(mBuffer);
    }

    /**
     * Add the given packet buffer to the end of the buffer chain, adjusting the total length of each buffer in the chain
     * accordingly.
     *
     *  @note The current packet buffer handle must either be the head of the buffer chain for the lengths to be adjusted properly,
     *        or be null (in which case it becomes the head).
     *
     *  @note Ownership is transferred from the argument to the `next` link at the end of the current chain,
     *        or to the handle if it's currently null.
     *
     *  @param[in] aPacket - the packet buffer to be added to the end of the current chain.
     */
    void AddToEnd(PacketBufferHandle && aPacket)
    {
        if (IsNull())
        {
            mBuffer         = aPacket.mBuffer;
            aPacket.mBuffer = nullptr;
        }
        else
        {
            mBuffer->AddToEnd(std::move(aPacket));
        }
    }

    /**
     * Consume data in a chain of buffers.
     *
     *  Consume data in a chain of buffers starting with the current buffer and proceeding through the remaining buffers in the
     *  chain. Each buffer that is completely consumed is freed and the handle holds the first buffer (if any) containing the
     *  remaining data. The current buffer must be the head of the buffer chain.
     *
     *  @param[in] aConsumeLength - number of bytes to consume from the current chain.
     */
    void Consume(uint16_t aConsumeLength) { mBuffer = mBuffer->Consume(aConsumeLength); }

    /**
     * Copy the given buffer to a right-sized buffer if applicable.
     *
     * Only operates on single buffers (for chains, use \c CompactHead() and RightSize the tail).
     * Requires that this handle be the only reference to the underlying buffer.
     */
    void RightSize()
    {
#if CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE
        InternalRightSize();
#endif
    }

    /**
     * Get a new handle to a raw PacketBuffer pointer.
     *
     * @brief The caller's ownership is transferred to this.
     *
     * @note This should only be used in low-level code, e.g. to import buffers from LwIP or a similar stack.
     */
    static PacketBufferHandle Adopt(PacketBuffer * buffer) { return PacketBufferHandle(buffer); }
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    static PacketBufferHandle Adopt(pbuf * buffer) { return Adopt(reinterpret_cast<PacketBuffer *>(buffer)); }
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

    /**
     * Advance this PacketBufferHandle to the next buffer in a chain.
     *
     *  @note This differs from `FreeHead()` in that it does not touch any content in the currently referenced packet buffer;
     *      it only changes which buffer this handle owns. (Note that this could result in the previous buffer being freed,
     *      if there is no other owner.) `Advance()` is designed to be used with an additional handle to traverse a buffer chain,
     *      whereas `FreeHead()` modifies a chain.
     */
    void Advance() { *this = Hold(mBuffer->ChainedBuffer()); }

    /**
     * Export a raw PacketBuffer pointer.
     *
     * @brief The PacketBufferHandle's ownership is transferred to the caller.
     *
     * @note This should only be used in low-level code. The caller owns one counted reference to the \c PacketBuffer
     *       and is responsible for managing it safely.
     *
     * @note The ref-qualifier `&&` requires the caller to use `std::move` to emphasize that ownership is
     *       moved out of this handle.
     */
    CHECK_RETURN_VALUE PacketBuffer * UnsafeRelease() &&
    {
        PacketBuffer::Check(mBuffer);
        PacketBuffer * buffer = mBuffer;
        mBuffer               = nullptr;
        return buffer;
    }

    /**
     * Allocates a packet buffer.
     *
     *  A packet buffer is conceptually divided into two parts:
     *  @li  Space reserved for network protocol headers. The size of this space normally defaults to a value determined
     *       by the network layer configuration, but can be given explicity by \c aReservedSize for special cases.
     *  @li  Space for application data. The minimum size of this space is given by \c aAvailableSize, and then \c Start()
     *       provides a pointer to the start of this space.
     *
     *  Fails and returns \c nullptr if no memory is available, or if the size requested is too large.
     *  When the sum of \a aAvailableSize and \a aReservedSize is no greater than \c PacketBuffer::kMaxSizeWithoutReserve,
     *  that is guaranteed not to be too large.
     *
     *  On success, it is guaranteed that \c AvailableDataSize() is no less than \a aAvailableSize.
     *
     *  @param[in]  aAvailableSize  Minimum number of octets to for application data (at `Start()`).
     *  @param[in]  aReservedSize   Number of octets to reserve for protocol headers (before `Start()`).
     *
     *  @return     On success, a PacketBufferHandle to the allocated buffer. On fail, \c nullptr.
     */
    static PacketBufferHandle New(size_t aAvailableSize, uint16_t aReservedSize = PacketBuffer::kDefaultHeaderReserve);

    /**
     * Allocates a packet buffer with initial contents.
     *
     *  @param[in]  aData           Initial buffer contents.
     *  @param[in]  aDataSize       Size of initial buffer contents.
     *  @param[in]  aAdditionalSize Size of additional application data space after the initial contents.
     *  @param[in]  aReservedSize   Number of octets to reserve for protocol headers.
     *
     *  @return     On success, a PacketBufferHandle to the allocated buffer. On fail, \c nullptr.
     */
    static PacketBufferHandle NewWithData(const void * aData, size_t aDataSize, uint16_t aAdditionalSize = 0,
                                          uint16_t aReservedSize = PacketBuffer::kDefaultHeaderReserve);

    /**
     * Creates a copy of a packet buffer (or chain).
     *
     * @returns empty handle on allocation failure. Otherwise, the returned buffer has the same sizes and contents as the original.
     */
    PacketBufferHandle CloneData() const;

    /**
     * Perform an implementation-defined check on the validity of a PacketBufferHandle.
     *
     * Unless enabled by #CHIP_CONFIG_MEMORY_DEBUG_CHECKS == 1, this function does nothing.
     *
     * When enabled, it performs an implementation- and configuration-defined check on
     * the validity of the packet buffer. It MAY log an error and/or abort the program
     * if the packet buffer or the implementation-defined memory management system is in
     * a faulty state. (Some configurations may not actually perform any check.)
     *
     * @note  A null handle is not considered faulty.
     */
    void Check() const
    {
#if CHIP_SYSTEM_PACKETBUFFER_HAS_CHECK
        PacketBuffer::Check(mBuffer);
#endif
    }

protected:
#if CHIP_SYSTEM_CONFIG_USE_LWIP
    // For use via LwIPPacketBufferView only.
    static struct pbuf * GetLwIPpbuf(const PacketBufferHandle & handle)
    {
        PacketBuffer::Check(handle.mBuffer);
        return static_cast<struct pbuf *>(handle.mBuffer);
    }
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

private:
    PacketBufferHandle(const PacketBufferHandle &) = delete;
    PacketBufferHandle & operator=(const PacketBufferHandle &) = delete;

    // The caller's ownership is transferred to this.
    explicit PacketBufferHandle(PacketBuffer * buffer) : mBuffer(buffer) {}

    static PacketBufferHandle Hold(PacketBuffer * buffer)
    {
        if (buffer != nullptr)
        {
            buffer->AddRef();
        }
        return PacketBufferHandle(buffer);
    }

    PacketBuffer * Get() const { return mBuffer; }

    bool operator==(const PacketBufferHandle & aOther) { return mBuffer == aOther.mBuffer; }

#if CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE
    void InternalRightSize();
#endif

    PacketBuffer * mBuffer;

    friend class PacketBuffer;
    friend class ::PacketBufferTest;
};

inline void PacketBuffer::SetDataLength(uint16_t aNewLen, const PacketBufferHandle & aChainHead)
{
    SetDataLength(aNewLen, aChainHead.mBuffer);
}

inline PacketBufferHandle PacketBuffer::Next()
{
    return PacketBufferHandle::Hold(ChainedBuffer());
}

inline PacketBufferHandle PacketBuffer::Last()
{
    PacketBuffer * p = this;
    while (p->HasChainedBuffer())
        p = p->ChainedBuffer();
    return PacketBufferHandle::Hold(p);
}

} // namespace System

namespace Encoding {

class PacketBufferWriterUtil
{
private:
    template <typename>
    friend class PacketBufferWriterBase;
    static System::PacketBufferHandle Finalize(BufferWriter & aBufferWriter, System::PacketBufferHandle & aPacket);
};

/**
 * BufferWriter backed by packet buffer.
 *
 * Typical use:
 *  @code
 *      PacketBufferWriter buf(maximumLength);
 *      if (buf.IsNull()) { return CHIP_ERROR_NO_MEMORY; }
 *      buf.Put(...);
 *      ...
 *      PacketBufferHandle handle = buf.Finalize();
 *      if (buf.IsNull()) { return CHIP_ERROR_BUFFER_TOO_SMALL; }
 *      // valid data
 *  @endcode
 */
template <class Writer>
class PacketBufferWriterBase : public Writer
{
public:
    /**
     * Constructs a BufferWriter that writes into a packet buffer, using all available space.
     *
     *  @param[in]  aPacket  A handle to PacketBuffer, to be used as backing store for the BufferWriter.
     */
    PacketBufferWriterBase(System::PacketBufferHandle && aPacket) :
        Writer(aPacket->Start() + aPacket->DataLength(), aPacket->AvailableDataLength())
    {
        mPacket = std::move(aPacket);
    }

    /**
     * Constructs a BufferWriter that writes into a packet buffer, using no more than the requested space.
     *
     *  @param[in]  aPacket A handle to PacketBuffer, to be used as backing store for the BufferWriter.
     *  @param[in]  aSize   Maximum number of octects to write into the packet buffer.
     */
    PacketBufferWriterBase(System::PacketBufferHandle && aPacket, size_t aSize) :
        Writer(aPacket->Start() + aPacket->DataLength(), chip::min(aSize, static_cast<size_t>(aPacket->AvailableDataLength())))
    {
        mPacket = std::move(aPacket);
    }

    /**
     * Test whether this PacketBufferWriter is null, or conversely owns a PacketBuffer.
     *
     * @retval true     The PacketBufferWriter is null; it does not own a PacketBuffer. This implies either that
     *                  construction failed, or that \c Finalize() has previously been called to release the buffer.
     * @retval false    The PacketBufferWriter owns a PacketBuffer, which can be written using BufferWriter \c Put() methods,
     *                  and (assuming no overflow) obtained by calling \c Finalize().
     */
    bool IsNull() const { return mPacket.IsNull(); }

    /**
     * Obtain the backing packet buffer, if it is valid.
     *
     *  If construction succeeded, \c Finalize() has not already been called, and \c BufferWriter::Fit() is true,
     *  the caller takes ownership of a buffer containing the desired data. Otherwise, the returned handle tests null,
     *  and any underlying storage has been released.
     *
     *  @return     A packet buffer handle.
     */
    System::PacketBufferHandle Finalize() { return PacketBufferWriterUtil::Finalize(*this, mPacket); }

private:
    System::PacketBufferHandle mPacket;
};

using PacketBufferWriter = PacketBufferWriterBase<chip::Encoding::BufferWriter>;

namespace LittleEndian {
using PacketBufferWriter = PacketBufferWriterBase<chip::Encoding::LittleEndian::BufferWriter>;
} // namespace LittleEndian

namespace BigEndian {
using PacketBufferWriter = PacketBufferWriterBase<chip::Encoding::BigEndian::BufferWriter>;
} // namespace BigEndian

} // namespace Encoding

} // namespace chip

#if CHIP_SYSTEM_CONFIG_USE_LWIP

namespace chip {

namespace Inet {
class UDPEndPointImplLwIP;
} // namespace Inet

namespace System {

/**
 * Provide low-level access to a raw `pbuf *`, limited to specific classes that interface with LwIP.
 */
class LwIPPacketBufferView : public PacketBufferHandle
{
private:
    /**
     * Borrow a raw LwIP `pbuf *`.
     *
     * @brief The caller has access but no ownership.
     *
     * @note This should be used ONLY by low-level code interfacing with LwIP.
     */
    static struct pbuf * UnsafeGetLwIPpbuf(const PacketBufferHandle & handle) { return PacketBufferHandle::GetLwIPpbuf(handle); }
    friend class Inet::UDPEndPointImplLwIP;
};

} // namespace System
} // namespace chip

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
