/*
 *
 *    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::chipTLVReader
 *          @ref chip::chipTLVWriter
 *
 * ### 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);

    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
