/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes definitions for the message buffer pool and message buffers.
 */

#ifndef MESSAGE_HPP_
#define MESSAGE_HPP_

#include "openthread-core-config.h"

#include <stdint.h>

#include <openthread/message.h>
#include <openthread/platform/messagepool.h>

#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/code_utils.hpp"
#include "common/const_cast.hpp"
#include "common/data.hpp"
#include "common/encoding.hpp"
#include "common/iterator_utils.hpp"
#include "common/linked_list.hpp"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "common/pool.hpp"
#include "common/timer.hpp"
#include "common/type_traits.hpp"
#include "mac/mac_types.hpp"
#include "thread/child_mask.hpp"
#include "thread/link_quality.hpp"

/**
 * This struct represents an opaque (and empty) type for an OpenThread message buffer.
 *
 */
struct otMessage
{
};

namespace ot {

namespace Crypto {

class AesCcm;
class Sha256;
class HmacSha256;

} // namespace Crypto

/**
 * @addtogroup core-message
 *
 * @brief
 *   This module includes definitions for the message buffer pool and message buffers.
 *
 * @{
 *
 */

/**
 * This macro frees a given message buffer if not `nullptr`.
 *
 * This macro and the ones that follow contain small but common code patterns used in many of the core modules. They
 * are intentionally defined as macros instead of inline methods/functions to ensure that they are fully inlined.
 * Note that an `inline` method/function is not necessarily always inlined by the toolchain and not inlining such
 * small implementations can add a rather large code-size overhead.
 *
 * @param[in] aMessage    A pointer to a `Message` to free (can be `nullptr`).
 *
 */
#define FreeMessage(aMessage)      \
    do                             \
    {                              \
        if ((aMessage) != nullptr) \
        {                          \
            (aMessage)->Free();    \
        }                          \
    } while (false)

/**
 * This macro frees a given message buffer if a given `Error` indicates an error.
 *
 * The parameter @p aMessage can be `nullptr` in which case this macro does nothing.
 *
 * @param[in] aMessage    A pointer to a `Message` to free (can be `nullptr`).
 * @param[in] aError      The `Error` to check.
 *
 */
#define FreeMessageOnError(aMessage, aError)                     \
    do                                                           \
    {                                                            \
        if (((aError) != kErrorNone) && ((aMessage) != nullptr)) \
        {                                                        \
            (aMessage)->Free();                                  \
        }                                                        \
    } while (false)

/**
 * This macro frees a given message buffer if a given `Error` indicates an error and sets the `aMessage` to `nullptr`.
 *
 * @param[in] aMessage    A pointer to a `Message` to free (can be `nullptr`).
 * @param[in] aError      The `Error` to check.
 *
 */
#define FreeAndNullMessageOnError(aMessage, aError)              \
    do                                                           \
    {                                                            \
        if (((aError) != kErrorNone) && ((aMessage) != nullptr)) \
        {                                                        \
            (aMessage)->Free();                                  \
            (aMessage) = nullptr;                                \
        }                                                        \
    } while (false)

constexpr uint16_t kNumBuffers = OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS;
constexpr uint16_t kBufferSize = OPENTHREAD_CONFIG_MESSAGE_BUFFER_SIZE;

class Message;
class MessagePool;
class MessageQueue;
class PriorityQueue;
class ThreadLinkInfo;

/**
 * This class represents a Message buffer.
 *
 */
class Buffer : public otMessageBuffer, public LinkedListEntry<Buffer>
{
    friend class Message;

public:
    /**
     * This method returns a pointer to the next message buffer.
     *
     * @returns A pointer to the next message buffer.
     *
     */
    Buffer *GetNextBuffer(void) { return GetNext(); }

    /**
     * This method returns a pointer to the next message buffer.
     *
     * @returns A pointer to the next message buffer.
     *
     */
    const Buffer *GetNextBuffer(void) const { return GetNext(); }

    /**
     * This method sets the pointer to the next message buffer.
     *
     * @param[in] aNext  A pointer to the next buffer.
     *
     */
    void SetNextBuffer(Buffer *aNext) { SetNext(aNext); }

protected:
    struct Metadata
    {
        Message *    mNext;        // Next message in a doubly linked list.
        Message *    mPrev;        // Previous message in a doubly linked list.
        MessagePool *mMessagePool; // Message pool for this message.
        void *       mQueue;       // The queue where message is queued (if any). Queue type from `mInPriorityQ`.
        uint32_t     mDatagramTag; // The datagram tag used for 6LoWPAN frags or IPv6fragmentation.
        TimeMilli    mTimestamp;   // The message timestamp.
        uint16_t     mReserved;    // Number of reserved bytes (for header).
        uint16_t     mLength;      // Current message length (number of bytes).
        uint16_t     mOffset;      // A byte offset within the message.
        uint16_t     mMeshDest;    // Used for unicast non-link-local messages.
        uint16_t     mPanId;       // PAN ID (used for MLE Discover Request and Response).
        uint8_t      mChannel;     // The message channel (used for MLE Announce).
        RssAverager  mRssAverager; // The averager maintaining the received signal strength (RSS) average.
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
        LqiAverager mLqiAverager; // The averager maintaining the Link quality indicator (LQI) average.
#endif
        ChildMask mChildMask; // ChildMask to indicate which sleepy children need to receive this.

        uint8_t mType : 3;             // The message type.
        uint8_t mSubType : 4;          // The message sub type.
        bool    mDirectTx : 1;         // Whether a direct transmission is required.
        bool    mLinkSecurity : 1;     // Whether link security is enabled.
        uint8_t mPriority : 2;         // The message priority level (higher value is higher priority).
        bool    mInPriorityQ : 1;      // Whether the message is queued in normal or priority queue.
        bool    mTxSuccess : 1;        // Whether the direct tx of the message was successful.
        bool    mDoNotEvict : 1;       // Whether this message may be evicted.
        bool    mMulticastLoop : 1;    // Whether this multicast message may be looped back.
        bool    mResolvingAddress : 1; // Whether the message is pending an address query resolution.
#if OPENTHREAD_CONFIG_MULTI_RADIO
        uint8_t mRadioType : 2;      // The radio link type the message was received on, or should be sent on.
        bool    mIsRadioTypeSet : 1; // Whether the radio type is set.
        static_assert(Mac::kNumRadioTypes <= (1 << 2), "mRadioType bitfield cannot store all radio type values");
#endif
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
        bool    mTimeSync : 1;      // Whether the message is also used for time sync purpose.
        int64_t mNetworkTimeOffset; // The time offset to the Thread network time, in microseconds.
        uint8_t mTimeSyncSeq;       // The time sync sequence.
#endif
    };

    static_assert(kBufferSize > sizeof(Metadata) + sizeof(otMessageBuffer), "Metadata does not fit in a single buffer");

    static constexpr uint16_t kBufferDataSize     = kBufferSize - sizeof(otMessageBuffer);
    static constexpr uint16_t kHeadBufferDataSize = kBufferDataSize - sizeof(Metadata);

    Metadata &      GetMetadata(void) { return mBuffer.mHead.mMetadata; }
    const Metadata &GetMetadata(void) const { return mBuffer.mHead.mMetadata; }

    uint8_t *      GetFirstData(void) { return mBuffer.mHead.mData; }
    const uint8_t *GetFirstData(void) const { return mBuffer.mHead.mData; }

    uint8_t *      GetData(void) { return mBuffer.mData; }
    const uint8_t *GetData(void) const { return mBuffer.mData; }

private:
    union
    {
        struct
        {
            Metadata mMetadata;
            uint8_t  mData[kHeadBufferDataSize];
        } mHead;
        uint8_t mData[kBufferDataSize];
    } mBuffer;
};

static_assert(sizeof(Buffer) >= kBufferSize, "Buffer size if not valid");

/**
 * This class represents a message.
 *
 */
class Message : public otMessage, public Buffer
{
    friend class Checksum;
    friend class Crypto::HmacSha256;
    friend class Crypto::Sha256;
    friend class Crypto::AesCcm;
    friend class MessagePool;
    friend class MessageQueue;
    friend class PriorityQueue;

public:
    /**
     * This enumeration represents the message type.
     *
     */
    enum Type : uint8_t
    {
        kTypeIp6          = 0, ///< A full uncompressed IPv6 packet
        kType6lowpan      = 1, ///< A 6lowpan frame
        kTypeSupervision  = 2, ///< A child supervision frame.
        kTypeMacEmptyData = 3, ///< An empty MAC data frame.
        kTypeOther        = 4, ///< Other (data) message.
    };

    /**
     * This enumeration represents the message sub-type.
     *
     */
    enum SubType : uint8_t
    {
        kSubTypeNone                   = 0,  ///< None
        kSubTypeMleAnnounce            = 1,  ///< MLE Announce
        kSubTypeMleDiscoverRequest     = 2,  ///< MLE Discover Request
        kSubTypeMleDiscoverResponse    = 3,  ///< MLE Discover Response
        kSubTypeJoinerEntrust          = 4,  ///< Joiner Entrust
        kSubTypeMplRetransmission      = 5,  ///< MPL next retransmission message
        kSubTypeMleGeneral             = 6,  ///< General MLE
        kSubTypeJoinerFinalizeResponse = 7,  ///< Joiner Finalize Response
        kSubTypeMleChildUpdateRequest  = 8,  ///< MLE Child Update Request
        kSubTypeMleDataResponse        = 9,  ///< MLE Data Response
        kSubTypeMleChildIdRequest      = 10, ///< MLE Child ID Request
        kSubTypeMleDataRequest         = 11, ///< MLE Data Request
    };

    enum Priority : uint8_t
    {
        kPriorityLow    = OT_MESSAGE_PRIORITY_LOW,      ///< Low priority level.
        kPriorityNormal = OT_MESSAGE_PRIORITY_NORMAL,   ///< Normal priority level.
        kPriorityHigh   = OT_MESSAGE_PRIORITY_HIGH,     ///< High priority level.
        kPriorityNet    = OT_MESSAGE_PRIORITY_HIGH + 1, ///< Network Control priority level.
    };

    static constexpr uint8_t kNumPriorities = 4; ///< Number of priority levels.

    /**
     * This enumeration represents the link security mode (used by `Settings` constructor).
     *
     */
    enum LinkSecurityMode : bool
    {
        kNoLinkSecurity   = false, ///< Link security disabled (no link security).
        kWithLinkSecurity = true,  ///< Link security enabled.
    };

    /**
     * This enumeration represents the message ownership model when a `Message` instance is passed to a method/function.
     *
     */
    enum Ownership : uint8_t
    {
        /**
         * This value indicates that the method/function receiving a `Message` instance should take custody of the
         * message (e.g., the method should `Free()` the message if no longer needed).
         *
         */
        kTakeCustody,

        /**
         * This value indicates that the method/function receiving a `Message` instance does not own the message (e.g.,
         * it should not `Free()` or `Enqueue()` it in a queue). The receiving method/function should create a
         * copy/clone of the message to keep (if/when needed).
         *
         */
        kCopyToUse,
    };

    /**
     * This class represents settings used for creating a new message.
     *
     */
    class Settings : public otMessageSettings
    {
    public:
        /**
         * This constructor initializes the `Settings` object.
         *
         * @param[in]  aSecurityMode  A link security mode.
         * @param[in]  aPriority      A message priority.
         *
         */
        Settings(LinkSecurityMode aSecurityMode, Priority aPriority);

        /**
         * This constructor initializes the `Settings` with a given message priority and link security enabled.
         *
         * @param[in]  aPriority      A message priority.
         *
         */
        explicit Settings(Priority aPriority)
            : Settings(kWithLinkSecurity, aPriority)
        {
        }

        /**
         * This method gets the message priority.
         *
         * @returns The message priority.
         *
         */
        Priority GetPriority(void) const { return static_cast<Priority>(mPriority); }

        /**
         * This method indicates whether the link security should be enabled.
         *
         * @returns TRUE if link security should be enabled, FALSE otherwise.
         *
         */
        bool IsLinkSecurityEnabled(void) const { return mLinkSecurityEnabled; }

        /**
         * This static method converts a pointer to an `otMessageSettings` to a `Settings`.
         *
         * @param[in] aSettings  A pointer to `otMessageSettings` to covert from.
         *                       If it is `nullptr`, then the default settings `GetDefault()` will be used.
         *
         * @returns A reference to the converted `Settings` or the default if @p aSettings is `nullptr`.
         *
         */
        static const Settings &From(const otMessageSettings *aSettings);

        /**
         * This static method returns the default settings with link security enabled and `kPriorityNormal` priority.
         *
         * @returns A reference to the default settings (link security enable and `kPriorityNormal` priority).
         *
         */
        static const Settings &GetDefault(void) { return static_cast<const Settings &>(kDefault); }

    private:
        static const otMessageSettings kDefault;
    };

    /**
     * This method frees this message buffer.
     *
     */
    void Free(void);

    /**
     * This method returns a pointer to the next message.
     *
     * @returns A pointer to the next message in the list or `nullptr` if at the end of the list.
     *
     */
    Message *GetNext(void) const;

    /**
     * This method returns the number of bytes in the message.
     *
     * @returns The number of bytes in the message.
     *
     */
    uint16_t GetLength(void) const { return GetMetadata().mLength; }

    /**
     * This method sets the number of bytes in the message.
     *
     * @param[in]  aLength  Requested number of bytes in the message.
     *
     * @retval kErrorNone    Successfully set the length of the message.
     * @retval kErrorNoBufs  Failed to grow the size of the message because insufficient buffers were available.
     *
     */
    Error SetLength(uint16_t aLength);

    /**
     * This method returns the number of buffers in the message.
     *
     */
    uint8_t GetBufferCount(void) const;

    /**
     * This method returns the byte offset within the message.
     *
     * @returns A byte offset within the message.
     *
     */
    uint16_t GetOffset(void) const { return GetMetadata().mOffset; }

    /**
     * This method moves the byte offset within the message.
     *
     * @param[in]  aDelta  The number of bytes to move the current offset, which may be positive or negative.
     *
     */
    void MoveOffset(int aDelta);

    /**
     * This method sets the byte offset within the message.
     *
     * @param[in]  aOffset  The byte offset within the message.
     *
     */
    void SetOffset(uint16_t aOffset);

    /**
     * This method returns the type of the message.
     *
     * @returns The type of the message.
     *
     */
    Type GetType(void) const { return static_cast<Type>(GetMetadata().mType); }

    /**
     * This method sets the message type.
     *
     * @param[in]  aType  The message type.
     *
     */
    void SetType(Type aType) { GetMetadata().mType = aType; }

    /**
     * This method returns the sub type of the message.
     *
     * @returns The sub type of the message.
     *
     */
    SubType GetSubType(void) const { return static_cast<SubType>(GetMetadata().mSubType); }

    /**
     * This method sets the message sub type.
     *
     * @param[in]  aSubType  The message sub type.
     *
     */
    void SetSubType(SubType aSubType) { GetMetadata().mSubType = aSubType; }

    /**
     * This method returns whether or not the message is of MLE subtype.
     *
     * @retval TRUE   If message is of MLE subtype.
     * @retval FALSE  If message is not of MLE subtype.
     *
     */
    bool IsSubTypeMle(void) const;

    /**
     * This method checks whether this multicast message may be looped back.
     *
     * @retval TRUE   If message may be looped back.
     * @retval FALSE  If message must not be looped back.
     *
     */
    bool GetMulticastLoop(void) const { return GetMetadata().mMulticastLoop; }

    /**
     * This method sets whether multicast may be looped back.
     *
     * @param[in]  aMulticastLoop  Whether allow looping back multicast.
     *
     */
    void SetMulticastLoop(bool aMulticastLoop) { GetMetadata().mMulticastLoop = aMulticastLoop; }

    /**
     * This method returns the message priority level.
     *
     * @returns The priority level associated with this message.
     *
     */
    Priority GetPriority(void) const { return static_cast<Priority>(GetMetadata().mPriority); }

    /**
     * This method sets the messages priority.
     * If the message is already queued in a priority queue, changing the priority ensures to
     * update the message in the associated queue.
     *
     * @param[in]  aPriority  The message priority level.
     *
     * @retval kErrorNone          Successfully set the priority for the message.
     * @retval kErrorInvalidArgs   Priority level is not invalid.
     *
     */
    Error SetPriority(Priority aPriority);

    /**
     * This static method convert a `Priority` to a string.
     *
     * @param[in] aPriority  The priority level.
     *
     * @returns A string representation of @p aPriority.
     *
     */
    static const char *PriorityToString(Priority aPriority);

    /**
     * This method prepends bytes to the front of the message.
     *
     * On success, this method grows the message by @p aLength bytes.
     *
     * @param[in]  aBuf     A pointer to a data buffer (can be `nullptr` to grow message without writing bytes).
     * @param[in]  aLength  The number of bytes to prepend.
     *
     * @retval kErrorNone    Successfully prepended the bytes.
     * @retval kErrorNoBufs  Not enough reserved bytes in the message.
     *
     */
    Error PrependBytes(const void *aBuf, uint16_t aLength);

    /**
     * This method prepends an object to the front of the message.
     *
     * On success, this method grows the message by the size of the object.
     *
     * @tparam    ObjectType   The object type to prepend to the message.
     *
     * @param[in] aObject      A reference to the object to prepend to the message.
     *
     * @retval kErrorNone    Successfully prepended the object.
     * @retval kErrorNoBufs  Not enough reserved bytes in the message.
     *
     */
    template <typename ObjectType> Error Prepend(const ObjectType &aObject)
    {
        static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");

        return PrependBytes(&aObject, sizeof(ObjectType));
    }

    /**
     * This method removes header bytes from the message.
     *
     * @param[in]  aLength  Number of header bytes to remove.
     *
     */
    void RemoveHeader(uint16_t aLength);

    /**
     * This method appends bytes to the end of the message.
     *
     * On success, this method grows the message by @p aLength bytes.
     *
     * @param[in]  aBuf     A pointer to a data buffer (MUST not be `nullptr`).
     * @param[in]  aLength  The number of bytes to append.
     *
     * @retval kErrorNone    Successfully appended the bytes.
     * @retval kErrorNoBufs  Insufficient available buffers to grow the message.
     *
     */
    Error AppendBytes(const void *aBuf, uint16_t aLength);

    /**
     * This method appends bytes read from another or potentially the same message to the end of the current message.
     *
     * On success, this method grows the message by @p aLength bytes.
     *
     * @param[in] aMessage   The message to read the bytes from (it can be the same as the current message).
     * @param[in] aOffset    The offset in @p aMessage to start reading the bytes from.
     * @param[in] aLength    The number of bytes to read from @p aMessage and append.
     *
     * @retval kErrorNone    Successfully appended the bytes.
     * @retval kErrorNoBufs  Insufficient available buffers to grow the message.
     * @retval kErrorParse   Not enough bytes in @p aMessage to read @p aLength bytes from @p aOffset.
     *
     */
    Error AppendBytesFromMessage(const Message &aMessage, uint16_t aOffset, uint16_t aLength);

    /**
     * This method appends an object to the end of the message.
     *
     * On success, this method grows the message by the size of the appended object
     *
     * @tparam    ObjectType   The object type to append to the message.
     *
     * @param[in] aObject      A reference to the object to append to the message.
     *
     * @retval kErrorNone    Successfully appended the object.
     * @retval kErrorNoBufs  Insufficient available buffers to grow the message.
     *
     */
    template <typename ObjectType> Error Append(const ObjectType &aObject)
    {
        static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");

        return AppendBytes(&aObject, sizeof(ObjectType));
    }

    /**
     * This method reads bytes from the message.
     *
     * @param[in]  aOffset  Byte offset within the message to begin reading.
     * @param[out] aBuf     A pointer to a data buffer to copy the read bytes into.
     * @param[in]  aLength  Number of bytes to read.
     *
     * @returns The number of bytes read.
     *
     */
    uint16_t ReadBytes(uint16_t aOffset, void *aBuf, uint16_t aLength) const;

    /**
     * This method reads a given number of bytes from the message.
     *
     * If there are fewer bytes available in the message than the requested read length, the available bytes will be
     * read and copied into @p aBuf. In this case `kErrorParse` will be returned.
     *
     * @param[in]  aOffset  Byte offset within the message to begin reading.
     * @param[out] aBuf     A pointer to a data buffer to copy the read bytes into.
     * @param[in]  aLength  Number of bytes to read.
     *
     * @retval kErrorNone     @p aLength bytes were successfully read from message.
     * @retval kErrorParse    Not enough bytes remaining in message to read the entire object.
     *
     */
    Error Read(uint16_t aOffset, void *aBuf, uint16_t aLength) const;

    /**
     * This method reads an object from the message.
     *
     * If there are fewer bytes available in the message than the requested object size, the available bytes will be
     * read and copied into @p aObject (@p aObject will be read partially). In this case `kErrorParse` will
     * be returned.
     *
     * @tparam     ObjectType   The object type to read from the message.
     *
     * @param[in]  aOffset      Byte offset within the message to begin reading.
     * @param[out] aObject      A reference to the object to read into.
     *
     * @retval kErrorNone     Object @p aObject was successfully read from message.
     * @retval kErrorParse    Not enough bytes remaining in message to read the entire object.
     *
     */
    template <typename ObjectType> Error Read(uint16_t aOffset, ObjectType &aObject) const
    {
        static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");

        return Read(aOffset, &aObject, sizeof(ObjectType));
    }

    /**
     * This method compares the bytes in the message at a given offset with a given byte array.
     *
     * If there are fewer bytes available in the message than the requested @p aLength, the comparison is treated as
     * failure (returns FALSE).
     *
     * @param[in]  aOffset    Byte offset within the message to read from for the comparison.
     * @param[in]  aBuf       A pointer to a data buffer to compare with the bytes from message.
     * @param[in]  aLength    Number of bytes in @p aBuf.
     * @param[in]  aMatcher   A `ByteMatcher` function pointer to match the bytes. If `nullptr` then bytes are directly
     *                        compared.
     *
     * @returns TRUE if there are enough bytes available in @p aMessage and they match the bytes from @p aBuf,
     *          FALSE otherwise.
     *
     */
    bool CompareBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength, ByteMatcher aMatcher = nullptr) const;

    /**
     * This method compares the bytes in the message at a given offset with bytes read from another message.
     *
     * If either message has fewer bytes available than the requested @p aLength, the comparison is treated as failure
     * (returns FALSE).
     *
     * @param[in]  aOffset        Byte offset within the message to read from for the comparison.
     * @param[in]  aOtherMessage  The other message to compare with.
     * @param[in]  aOtherOffset   Byte offset within @p aOtherMessage to read from for the comparison.
     * @param[in]  aLength        Number of bytes to compare.
     * @param[in]  aMatcher       A `ByteMatcher` function pointer to match the bytes. If `nullptr` then bytes are
     *                            directly compared.
     *
     * @returns TRUE if there are enough bytes available in both messages and they all match. FALSE otherwise.
     *
     */
    bool CompareBytes(uint16_t       aOffset,
                      const Message &aOtherMessage,
                      uint16_t       aOtherOffset,
                      uint16_t       aLength,
                      ByteMatcher    aMatcher = nullptr) const;

    /**
     * This method compares the bytes in the message at a given offset with an object.
     *
     * The bytes in the message are compared with the bytes in @p aObject. If there are fewer bytes available in the
     * message than the requested object size, it is treated as failed comparison (returns FALSE).
     *
     * @tparam     ObjectType   The object type to compare with the bytes in message.
     *
     * @param[in] aOffset      Byte offset within the message to read from for the comparison.
     * @param[in] aObject      A reference to the object to compare with the message bytes.
     *
     * @returns TRUE if there are enough bytes available in @p aMessage and they match the bytes in @p aObject,
     *          FALSE otherwise.
     *
     */
    template <typename ObjectType> bool Compare(uint16_t aOffset, const ObjectType &aObject) const
    {
        static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");

        return CompareBytes(aOffset, &aObject, sizeof(ObjectType));
    }

    /**
     * This method writes bytes to the message.
     *
     * This method will not resize the message. The given data to write (with @p aLength bytes) MUST fit within the
     * existing message buffer (from the given offset @p aOffset up to the message's length).
     *
     * @param[in]  aOffset  Byte offset within the message to begin writing.
     * @param[in]  aBuf     A pointer to a data buffer.
     * @param[in]  aLength  Number of bytes to write.
     *
     */
    void WriteBytes(uint16_t aOffset, const void *aBuf, uint16_t aLength);

    /**
     * This methods writes an object to the message.
     *
     * This method will not resize the message. The entire given object (all its bytes) MUST fit within the existing
     * message buffer (from the given offset @p aOffset up to the message's length).
     *
     * @tparam     ObjectType   The object type to write to the message.
     *
     * @param[in]  aOffset      Byte offset within the message to begin writing.
     * @param[in]  aObject      A reference to the object to write.
     *
     */
    template <typename ObjectType> void Write(uint16_t aOffset, const ObjectType &aObject)
    {
        static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");

        WriteBytes(aOffset, &aObject, sizeof(ObjectType));
    }

    /**
     * This method copies bytes from one message to another.
     *
     * If source and destination messages are the same, `CopyTo()` can be used to perform a backward copy, but
     * it MUST not be used to forward copy within the same message (i.e., when source and destination messages are the
     * same and source offset is smaller than the destination offset).
     *
     * @param[in] aSourceOffset       Byte offset within the source message to begin reading.
     * @param[in] aDestinationOffset  Byte offset within the destination message to begin writing.
     * @param[in] aLength             Number of bytes to copy.
     * @param[in] aMessage            Message to copy to.
     *
     * @returns The number of bytes copied.
     *
     */
    uint16_t CopyTo(uint16_t aSourceOffset, uint16_t aDestinationOffset, uint16_t aLength, Message &aMessage) const;

    /**
     * This method creates a copy of the message.
     *
     * It allocates the new message from the same message pool as the original one and copies @p aLength octets
     * of the payload. The `Type`, `SubType`, `LinkSecurity`, `Offset`, `InterfaceId`, and `Priority` fields on the
     * cloned message are also copied from the original one.
     *
     * @param[in] aLength  Number of payload bytes to copy.
     *
     * @returns A pointer to the message or nullptr if insufficient message buffers are available.
     *
     */
    Message *Clone(uint16_t aLength) const;

    /**
     * This method creates a copy of the message.
     *
     * It allocates the new message from the same message pool as the original one and copies the entire payload. The
     * `Type`, `SubType`, `LinkSecurity`, `Offset`, `InterfaceId`, and `Priority` fields on the cloned message are also
     * copied from the original one.
     *
     * @returns A pointer to the message or `nullptr` if insufficient message buffers are available.
     *
     */
    Message *Clone(void) const { return Clone(GetLength()); }

    /**
     * This method returns the datagram tag used for 6LoWPAN fragmentation or the identification used for IPv6
     * fragmentation.
     *
     * @returns The 6LoWPAN datagram tag or the IPv6 fragment identification.
     *
     */
    uint32_t GetDatagramTag(void) const { return GetMetadata().mDatagramTag; }

    /**
     * This method sets the datagram tag used for 6LoWPAN fragmentation.
     *
     * @param[in]  aTag  The 6LoWPAN datagram tag.
     *
     */
    void SetDatagramTag(uint32_t aTag) { GetMetadata().mDatagramTag = aTag; }

    /**
     * This method returns whether or not the message forwarding is scheduled for the child.
     *
     * @param[in]  aChildIndex  The index into the child table.
     *
     * @retval TRUE   If the message is scheduled to be forwarded to the child.
     * @retval FALSE  If the message is not scheduled to be forwarded to the child.
     *
     */
    bool GetChildMask(uint16_t aChildIndex) const;

    /**
     * This method unschedules forwarding of the message to the child.
     *
     * @param[in]  aChildIndex  The index into the child table.
     *
     */
    void ClearChildMask(uint16_t aChildIndex);

    /**
     * This method schedules forwarding of the message to the child.
     *
     * @param[in]  aChildIndex  The index into the child table.
     *
     */
    void SetChildMask(uint16_t aChildIndex);

    /**
     * This method returns whether or not the message forwarding is scheduled for at least one child.
     *
     * @retval TRUE   If message forwarding is scheduled for at least one child.
     * @retval FALSE  If message forwarding is not scheduled for any child.
     *
     */
    bool IsChildPending(void) const;

    /**
     * This method returns the RLOC16 of the mesh destination.
     *
     * @note Only use this for non-link-local unicast messages.
     *
     * @returns The IEEE 802.15.4 Destination PAN ID.
     *
     */
    uint16_t GetMeshDest(void) const { return GetMetadata().mMeshDest; }

    /**
     * This method sets the RLOC16 of the mesh destination.
     *
     * @note Only use this when sending non-link-local unicast messages.
     *
     * @param[in]  aMeshDest  The IEEE 802.15.4 Destination PAN ID.
     *
     */
    void SetMeshDest(uint16_t aMeshDest) { GetMetadata().mMeshDest = aMeshDest; }

    /**
     * This method returns the IEEE 802.15.4 Destination PAN ID.
     *
     * @note Only use this when sending MLE Discover Request or Response messages.
     *
     * @returns The IEEE 802.15.4 Destination PAN ID.
     *
     */
    uint16_t GetPanId(void) const { return GetMetadata().mPanId; }

    /**
     * This method sets the IEEE 802.15.4 Destination PAN ID.
     *
     * @note Only use this when sending MLE Discover Request or Response messages.
     *
     * @param[in]  aPanId  The IEEE 802.15.4 Destination PAN ID.
     *
     */
    void SetPanId(uint16_t aPanId) { GetMetadata().mPanId = aPanId; }

    /**
     * This method returns the IEEE 802.15.4 Channel to use for transmission.
     *
     * @note Only use this when sending MLE Announce messages.
     *
     * @returns The IEEE 802.15.4 Channel to use for transmission.
     *
     */
    uint8_t GetChannel(void) const { return GetMetadata().mChannel; }

    /**
     * This method sets the IEEE 802.15.4 Channel to use for transmission.
     *
     * @note Only use this when sending MLE Announce messages.
     *
     * @param[in]  aChannel  The IEEE 802.15.4 Channel to use for transmission.
     *
     */
    void SetChannel(uint8_t aChannel) { GetMetadata().mChannel = aChannel; }

    /**
     * This method returns the message timestamp.
     *
     * @returns The message timestamp.
     *
     */
    TimeMilli GetTimestamp(void) const { return GetMetadata().mTimestamp; }

    /**
     * This method sets the message timestamp to a given time.
     *
     * @param[in] aTimestamp   The timestamp value.
     *
     */
    void SetTimestamp(TimeMilli aTimestamp) { GetMetadata().mTimestamp = aTimestamp; }

    /**
     * This method sets the message timestamp to the current time.
     *
     */
    void SetTimestampToNow(void) { SetTimestamp(TimerMilli::GetNow()); }

    /**
     * This method returns whether or not message forwarding is scheduled for direct transmission.
     *
     * @retval TRUE   If message forwarding is scheduled for direct transmission.
     * @retval FALSE  If message forwarding is not scheduled for direct transmission.
     *
     */
    bool IsDirectTransmission(void) const { return GetMetadata().mDirectTx; }

    /**
     * This method unschedules forwarding using direct transmission.
     *
     */
    void ClearDirectTransmission(void) { GetMetadata().mDirectTx = false; }

    /**
     * This method schedules forwarding using direct transmission.
     *
     */
    void SetDirectTransmission(void) { GetMetadata().mDirectTx = true; }

    /**
     * This method indicates whether the direct transmission of message was successful.
     *
     * @retval TRUE   If direct transmission of message was successful (all fragments were delivered and acked).
     * @retval FALSE  If direct transmission of message failed (at least one fragment failed).
     *
     */
    bool GetTxSuccess(void) const { return GetMetadata().mTxSuccess; }

    /**
     * This method sets whether the direct transmission of message was successful.
     *
     * @param[in] aTxSuccess   TRUE if the direct transmission is successful, FALSE otherwise (i.e., at least one
     *                         fragment transmission failed).
     *
     */
    void SetTxSuccess(bool aTxSuccess) { GetMetadata().mTxSuccess = aTxSuccess; }

    /**
     * This method indicates whether the message may be evicted.
     *
     * @retval TRUE   If the message must not be evicted.
     * @retval FALSE  If the message may be evicted.
     *
     */
    bool GetDoNotEvict(void) const { return GetMetadata().mDoNotEvict; }

    /**
     * This method sets whether the message may be evicted.
     *
     * @param[in]  aDoNotEvict  TRUE if the message may not be evicted, FALSE otherwise.
     *
     */
    void SetDoNotEvict(bool aDoNotEvict) { GetMetadata().mDoNotEvict = aDoNotEvict; }

    /**
     * This method indicates whether the message is waiting for an address query resolution.
     *
     * @retval TRUE   If the message is waiting for address query resolution.
     * @retval FALSE  If the message is not waiting for address query resolution.
     *
     */
    bool IsResolvingAddress(void) const { return GetMetadata().mResolvingAddress; }

    /**
     * This method sets whether the message is waiting for an address query resolution.
     *
     * @param[in] aResolvingAddress    TRUE if message is waiting for address resolution, FALSE otherwise.
     *
     */
    void SetResolvingAddress(bool aResolvingAddress) { GetMetadata().mResolvingAddress = aResolvingAddress; }

    /**
     * This method indicates whether or not link security is enabled for the message.
     *
     * @retval TRUE   If link security is enabled.
     * @retval FALSE  If link security is not enabled.
     *
     */
    bool IsLinkSecurityEnabled(void) const { return GetMetadata().mLinkSecurity; }

    /**
     * This method sets whether or not link security is enabled for the message.
     *
     * @param[in]  aEnabled  TRUE if link security is enabled, FALSE otherwise.
     *
     */
    void SetLinkSecurityEnabled(bool aEnabled) { GetMetadata().mLinkSecurity = aEnabled; }

    /**
     * This method updates the average RSS (Received Signal Strength) associated with the message by adding the given
     * RSS value to the average. Note that a message can be composed of multiple 802.15.4 data frame fragments each
     * received with a different signal strength.
     *
     * @param[in] aRss A new RSS value (in dBm) to be added to average.
     *
     */
    void AddRss(int8_t aRss) { IgnoreError(GetMetadata().mRssAverager.Add(aRss)); }

    /**
     * This method returns the average RSS (Received Signal Strength) associated with the message.
     *
     * @returns The current average RSS value (in dBm) or OT_RADIO_RSSI_INVALID if no average is available.
     *
     */
    int8_t GetAverageRss(void) const { return GetMetadata().mRssAverager.GetAverage(); }

    /**
     * This method returns a const reference to RssAverager of the message.
     *
     * @returns A const reference to the RssAverager of the message.
     *
     */
    const RssAverager &GetRssAverager(void) const { return GetMetadata().mRssAverager; }

#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
    /**
     * This method updates the average LQI (Link Quality Indicator) associated with the message.
     *
     * The given LQI value would be added to the average. Note that a message can be composed of multiple 802.15.4
     * frame fragments each received with a different signal strength.
     *
     * @param[in] aLqi A new LQI value (has no unit) to be added to average.
     *
     */
    void AddLqi(uint8_t aLqi) { GetMetadata().mLqiAverager.Add(aLqi); }

    /**
     * This method returns the average LQI (Link Quality Indicator) associated with the message.
     *
     * @returns The current average LQI value (in dBm) or OT_RADIO_LQI_NONE if no average is available.
     *
     */
    uint8_t GetAverageLqi(void) const { return GetMetadata().mLqiAverager.GetAverage(); }

    /**
     * This method returns the count of frames counted so far.
     *
     * @returns The count of frames that have been counted.
     *
     */
    uint8_t GetPsduCount(void) const { return GetMetadata().mLqiAverager.GetCount(); }
#endif

    /**
     * This method sets the message's link info properties (PAN ID, link security, RSS) from a given `ThreadLinkInfo`.
     *
     * @param[in] aLinkInfo   The `ThreadLinkInfo` instance from which to set message's related properties.
     *
     */
    void SetLinkInfo(const ThreadLinkInfo &aLinkInfo);

    /**
     * This method returns a pointer to the message queue (if any) where this message is queued.
     *
     * @returns A pointer to the message queue or `nullptr` if not in any message queue.
     *
     */
    MessageQueue *GetMessageQueue(void) const
    {
        return !GetMetadata().mInPriorityQ ? static_cast<MessageQueue *>(GetMetadata().mQueue) : nullptr;
    }

    /**
     * This method returns a pointer to the priority message queue (if any) where this message is queued.
     *
     * @returns A pointer to the priority queue or `nullptr` if not in any priority queue.
     *
     */
    PriorityQueue *GetPriorityQueue(void) const
    {
        return GetMetadata().mInPriorityQ ? static_cast<PriorityQueue *>(GetMetadata().mQueue) : nullptr;
    }

    /**
     * This method indicates whether or not the message is also used for time sync purpose.
     *
     * When OPENTHREAD_CONFIG_TIME_SYNC_ENABLE is 0, this method always return false.
     *
     * @retval TRUE   If the message is also used for time sync purpose.
     * @retval FALSE  If the message is not used for time sync purpose.
     *
     */
    bool IsTimeSync(void) const;

#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
    /**
     * This method sets whether or not the message is also used for time sync purpose.
     *
     * @param[in]  aEnabled  TRUE if the message is also used for time sync purpose, FALSE otherwise.
     *
     */
    void SetTimeSync(bool aEnabled) { GetMetadata().mTimeSync = aEnabled; }

    /**
     * This method sets the offset to network time.
     *
     * @param[in]  aNetworkTimeOffset  The offset to network time.
     *
     */
    void SetNetworkTimeOffset(int64_t aNetworkTimeOffset) { GetMetadata().mNetworkTimeOffset = aNetworkTimeOffset; }

    /**
     * This method gets the offset to network time.
     *
     * @returns  The offset to network time.
     *
     */
    int64_t GetNetworkTimeOffset(void) const { return GetMetadata().mNetworkTimeOffset; }

    /**
     * This method sets the time sync sequence.
     *
     * @param[in]  aTimeSyncSeq  The time sync sequence.
     *
     */
    void SetTimeSyncSeq(uint8_t aTimeSyncSeq) { GetMetadata().mTimeSyncSeq = aTimeSyncSeq; }

    /**
     * This method gets the time sync sequence.
     *
     * @returns  The time sync sequence.
     *
     */
    uint8_t GetTimeSyncSeq(void) const { return GetMetadata().mTimeSyncSeq; }
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE

#if OPENTHREAD_CONFIG_MULTI_RADIO
    /**
     * This method indicates whether the radio type is set.
     *
     * @retval TRUE   If the radio type is set.
     * @retval FALSE  If the radio type is not set.
     *
     */
    bool IsRadioTypeSet(void) const { return GetMetadata().mIsRadioTypeSet; }

    /**
     * This method gets the radio link type the message was received on, or should be sent on.
     *
     * This method should be used only when `IsRadioTypeSet()` returns `true`.
     *
     * @returns The radio link type of the message.
     *
     */
    Mac::RadioType GetRadioType(void) const { return static_cast<Mac::RadioType>(GetMetadata().mRadioType); }

    /**
     * This method sets the radio link type the message was received on, or should be sent on.
     *
     * @param[in] aRadioType   A radio link type of the message.
     *
     */
    void SetRadioType(Mac::RadioType aRadioType)
    {
        GetMetadata().mIsRadioTypeSet = true;
        GetMetadata().mRadioType      = aRadioType;
    }

    /**
     * This method clears any previously set radio type on the message.
     *
     * After calling this method, `IsRadioTypeSet()` returns false until radio type is set (`SetRadioType()`).
     *
     */
    void ClearRadioType(void) { GetMetadata().mIsRadioTypeSet = false; }

#endif // #if OPENTHREAD_CONFIG_MULTI_RADIO

protected:
    class ConstIterator : public ItemPtrIterator<const Message, ConstIterator>
    {
        friend class ItemPtrIterator<const Message, ConstIterator>;

    public:
        ConstIterator(void) = default;

        explicit ConstIterator(const Message *aMessage)
            : ItemPtrIterator(aMessage)
        {
        }

    private:
        void Advance(void) { mItem = mItem->GetNext(); }
    };

    class Iterator : public ItemPtrIterator<Message, Iterator>
    {
        friend class ItemPtrIterator<Message, Iterator>;

    public:
        Iterator(void)
            : mNext(nullptr)
        {
        }

        explicit Iterator(Message *aMessage)
            : ItemPtrIterator(aMessage)
            , mNext(NextMessage(aMessage))
        {
        }

    private:
        void            Advance(void);
        static Message *NextMessage(Message *aMessage) { return (aMessage != nullptr) ? aMessage->GetNext() : nullptr; }

        Message *mNext;
    };

    uint16_t GetReserved(void) const { return GetMetadata().mReserved; }
    void     SetReserved(uint16_t aReservedHeader) { GetMetadata().mReserved = aReservedHeader; }

private:
    class Chunk : public Data<kWithUint16Length>
    {
    public:
        const Buffer *GetBuffer(void) const { return mBuffer; }
        void          SetBuffer(const Buffer *aBuffer) { mBuffer = aBuffer; }

    private:
        const Buffer *mBuffer; // Buffer containing the chunk
    };

    class MutableChunk : public Chunk
    {
    public:
        uint8_t *GetBytes(void) { return AsNonConst(Chunk::GetBytes()); }
    };

    void GetFirstChunk(uint16_t aOffset, uint16_t &aLength, Chunk &aChunk) const;
    void GetNextChunk(uint16_t &aLength, Chunk &aChunk) const;

    void GetFirstChunk(uint16_t aOffset, uint16_t &aLength, MutableChunk &aChunk)
    {
        AsConst(this)->GetFirstChunk(aOffset, aLength, static_cast<Chunk &>(aChunk));
    }

    void GetNextChunk(uint16_t &aLength, MutableChunk &aChunk)
    {
        AsConst(this)->GetNextChunk(aLength, static_cast<Chunk &>(aChunk));
    }

    MessagePool *GetMessagePool(void) const { return GetMetadata().mMessagePool; }
    void         SetMessagePool(MessagePool *aMessagePool) { GetMetadata().mMessagePool = aMessagePool; }

    bool IsInAQueue(void) const { return (GetMetadata().mQueue != nullptr); }
    void SetMessageQueue(MessageQueue *aMessageQueue);
    void SetPriorityQueue(PriorityQueue *aPriorityQueue);

    Message *&      Next(void) { return GetMetadata().mNext; }
    Message *const &Next(void) const { return GetMetadata().mNext; }
    Message *&      Prev(void) { return GetMetadata().mPrev; }

    static Message *      NextOf(Message *aMessage) { return (aMessage != nullptr) ? aMessage->Next() : nullptr; }
    static const Message *NextOf(const Message *aMessage) { return (aMessage != nullptr) ? aMessage->Next() : nullptr; }

    Error ResizeMessage(uint16_t aLength);
};

/**
 * This class implements a message queue.
 *
 */
class MessageQueue : public otMessageQueue
{
    friend class Message;
    friend class PriorityQueue;

public:
    typedef otMessageQueueInfo Info; ///< This struct represents info (number of messages/buffers) about a queue.

    /**
     * This enumeration represents a position (head or tail) in the queue. This is used to specify where a new message
     * should be added in the queue.
     *
     */
    enum QueuePosition : uint8_t
    {
        kQueuePositionHead, ///< Indicates the head (front) of the list.
        kQueuePositionTail, ///< Indicates the tail (end) of the list.
    };

    /**
     * This constructor initializes the message queue.
     *
     */
    MessageQueue(void) { SetTail(nullptr); }

    /**
     * This method returns a pointer to the first message.
     *
     * @returns A pointer to the first message.
     *
     */
    Message *GetHead(void) { return Message::NextOf(GetTail()); }

    /**
     * This method returns a pointer to the first message.
     *
     * @returns A pointer to the first message.
     *
     */
    const Message *GetHead(void) const { return Message::NextOf(GetTail()); }

    /**
     * This method adds a message to the end of the list.
     *
     * @param[in]  aMessage  The message to add.
     *
     */
    void Enqueue(Message &aMessage) { Enqueue(aMessage, kQueuePositionTail); }

    /**
     * This method adds a message at a given position (head/tail) of the list.
     *
     * @param[in]  aMessage  The message to add.
     * @param[in]  aPosition The position (head or tail) where to add the message.
     *
     */
    void Enqueue(Message &aMessage, QueuePosition aPosition);

    /**
     * This method removes a message from the list.
     *
     * @param[in]  aMessage  The message to remove.
     *
     */
    void Dequeue(Message &aMessage);

    /**
     * This method removes a message from the queue and frees it.
     *
     * @param[in]  aMessage  The message to remove and free.
     *
     */
    void DequeueAndFree(Message &aMessage);

    /**
     * This method removes and frees all messages from the queue.
     *
     */
    void DequeueAndFreeAll(void);

    /**
     * This method gets the information about number of messages and buffers in the queue.
     *
     * This method updates `aInfo` and adds number of message/buffers in the message queue to the corresponding member
     * variable in `aInfo`. The caller needs to make sure `aInfo` is initialized before calling this method (e.g.,
     * clearing `aInfo`). Same `aInfo` can be passed in multiple calls of `GetInfo(aInfo)` on different queues to add
     * up the number of messages/buffers on different queues.
     *
     * @param[out] aInfo  A reference to `Info` structure to update.ni
     *
     */
    void GetInfo(Info &aInfo) const;

    // The following methods are intended to support range-based `for`
    // loop iteration over the queue entries and should not be used
    // directly. The range-based `for` works correctly even if the
    // current entry is removed from the queue during iteration.

    Message::Iterator begin(void);
    Message::Iterator end(void) { return Message::Iterator(); }

    Message::ConstIterator begin(void) const;
    Message::ConstIterator end(void) const { return Message::ConstIterator(); }

private:
    Message *      GetTail(void) { return static_cast<Message *>(mData); }
    const Message *GetTail(void) const { return static_cast<const Message *>(mData); }
    void           SetTail(Message *aMessage) { mData = aMessage; }
};

/**
 * This class implements a priority queue.
 *
 */
class PriorityQueue : private Clearable<PriorityQueue>
{
    friend class Message;
    friend class MessageQueue;
    friend class MessagePool;

public:
    typedef otMessageQueueInfo Info; ///< This struct represents info (number of messages/buffers) about a queue.

    /**
     * This constructor initializes the priority queue.
     *
     */
    PriorityQueue(void) { Clear(); }

    /**
     * This method returns a pointer to the first message.
     *
     * @returns A pointer to the first message.
     *
     */
    Message *GetHead(void) { return AsNonConst(AsConst(this)->GetHead()); }

    /**
     * This method returns a pointer to the first message.
     *
     * @returns A pointer to the first message.
     *
     */
    const Message *GetHead(void) const;

    /**
     * This method returns a pointer to the first message for a given priority level.
     *
     * @param[in] aPriority   Priority level.
     *
     * @returns A pointer to the first message with given priority level or `nullptr` if there is no messages with
     *          this priority level.
     *
     */
    Message *GetHeadForPriority(Message::Priority aPriority)
    {
        return AsNonConst(AsConst(this)->GetHeadForPriority(aPriority));
    }

    /**
     * This method returns a pointer to the first message for a given priority level.
     *
     * @param[in] aPriority   Priority level.
     *
     * @returns A pointer to the first message with given priority level or `nullptr` if there is no messages with
     *          this priority level.
     *
     */
    const Message *GetHeadForPriority(Message::Priority aPriority) const;

    /**
     * This method adds a message to the queue.
     *
     * @param[in]  aMessage  The message to add.
     *
     */
    void Enqueue(Message &aMessage);

    /**
     * This method removes a message from the list.
     *
     * @param[in]  aMessage  The message to remove.
     *
     */
    void Dequeue(Message &aMessage);

    /**
     * This method removes a message from the queue and frees it.
     *
     * @param[in]  aMessage  The message to remove and free.
     *
     */
    void DequeueAndFree(Message &aMessage);

    /**
     * This method removes and frees all messages from the queue.
     *
     */
    void DequeueAndFreeAll(void);

    /**
     * This method returns the tail of the list (last message in the list).
     *
     * @returns A pointer to the tail of the list.
     *
     */
    Message *GetTail(void) { return AsNonConst(AsConst(this)->GetTail()); }

    /**
     * This method returns the tail of the list (last message in the list).
     *
     * @returns A pointer to the tail of the list.
     *
     */
    const Message *GetTail(void) const;

    /**
     * This method gets the information about number of messages and buffers in the priority queue.
     *
     * This method updates `aInfo` array and adds number of message/buffers in the message queue to the corresponding
     * member variable in `aInfo`. The caller needs to make sure `aInfo` is initialized before calling this method
     * (e.g., clearing `aInfo`). Same `aInfo` can be passed in multiple calls of `GetInfo(aInfo)` on different queues
     * to add up the number of messages/buffers on different queues.
     *
     * @param[out] aInfo  A reference to an `Info` structure to update.
     *
     */
    void GetInfo(Info &aInfo) const;

    // The following methods are intended to support range-based `for`
    // loop iteration over the queue entries and should not be used
    // directly. The range-based `for` works correctly even if the
    // current entry is removed from the queue during iteration.

    Message::Iterator begin(void);
    Message::Iterator end(void) { return Message::Iterator(); }

    Message::ConstIterator begin(void) const;
    Message::ConstIterator end(void) const { return Message::ConstIterator(); }

private:
    uint8_t PrevPriority(uint8_t aPriority) const
    {
        return (aPriority == Message::kNumPriorities - 1) ? 0 : (aPriority + 1);
    }

    const Message *FindFirstNonNullTail(Message::Priority aStartPriorityLevel) const;

    Message *FindFirstNonNullTail(Message::Priority aStartPriorityLevel)
    {
        return AsNonConst(AsConst(this)->FindFirstNonNullTail(aStartPriorityLevel));
    }

    Message *mTails[Message::kNumPriorities]; // Tail pointers associated with different priority levels.
};

/**
 * This class represents a message pool
 *
 */
class MessagePool : public InstanceLocator, private NonCopyable
{
    friend class Message;
    friend class MessageQueue;
    friend class PriorityQueue;

public:
    /**
     * This constructor initializes the object.
     *
     */
    explicit MessagePool(Instance &aInstance);

    /**
     * This method allocates a new message with specified settings.
     *
     * @param[in]  aType           The message type.
     * @param[in]  aReserveHeader  The number of header bytes to reserve.
     * @param[in]  aSettings       The message settings.
     *
     * @returns A pointer to the message or `nullptr` if no message buffers are available.
     *
     */
    Message *Allocate(Message::Type            aType,
                      uint16_t                 aReserveHeader = 0,
                      const Message::Settings &aSettings      = Message::Settings::GetDefault());

    /**
     * This method is used to free a message and return all message buffers to the buffer pool.
     *
     * @param[in]  aMessage  The message to free.
     *
     */
    void Free(Message *aMessage);

    /**
     * This method returns the number of free buffers.
     *
     * @returns The number of free buffers.
     *
     */
    uint16_t GetFreeBufferCount(void) const;

    /**
     * This method returns the total number of buffers.
     *
     * @returns The total number of buffers.
     *
     */
    uint16_t GetTotalBufferCount(void) const;

private:
    Buffer *NewBuffer(Message::Priority aPriority);
    void    FreeBuffers(Buffer *aBuffer);
    Error   ReclaimBuffers(Message::Priority aPriority);

#if !OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT && !OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE
    uint16_t                  mNumFreeBuffers;
    Pool<Buffer, kNumBuffers> mBufferPool;
#endif
};

/**
 * @}
 *
 */

DefineCoreType(otMessageBuffer, Buffer);
DefineCoreType(otMessageSettings, Message::Settings);
DefineCoreType(otMessage, Message);
DefineCoreType(otMessageQueue, MessageQueue);

} // namespace ot

#endif // MESSAGE_HPP_
