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

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_CONFIG_USE_LWIP
    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 TestSystemPacketBuffer;
};

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) const { return mBuffer == aOther.mBuffer; }

#if CHIP_SYSTEM_PACKETBUFFER_HAS_RIGHTSIZE
    void InternalRightSize();
#endif

    PacketBuffer * mBuffer;

    friend class PacketBuffer;
    friend class TestSystemPacketBuffer;
};

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
