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

#ifndef ICMP6_HPP_
#define ICMP6_HPP_

#include "openthread-core-config.h"

#include <openthread/icmp6.h>

#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/encoding.hpp"
#include "common/linked_list.hpp"
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "net/ip6_headers.hpp"

namespace ot {
namespace Ip6 {

using ot::Encoding::BigEndian::HostSwap16;

/**
 * @addtogroup core-ip6-icmp6
 *
 * @brief
 *   This module includes definitions for ICMPv6.
 *
 * @{
 *
 */

class Headers;

/**
 * This class implements ICMPv6.
 *
 */
class Icmp : public InstanceLocator, private NonCopyable
{
public:
    /*
     * This class implements ICMPv6 header generation and parsing.
     *
     */
    OT_TOOL_PACKED_BEGIN
    class Header : public otIcmp6Header, public Clearable<Header>
    {
    public:
        /**
         * ICMPv6 Message Types
         *
         */
        enum Type : uint8_t
        {
            kTypeDstUnreach       = OT_ICMP6_TYPE_DST_UNREACH,       ///< Destination Unreachable
            kTypePacketToBig      = OT_ICMP6_TYPE_PACKET_TO_BIG,     ///< Packet To Big
            kTypeTimeExceeded     = OT_ICMP6_TYPE_TIME_EXCEEDED,     ///< Time Exceeded
            kTypeParameterProblem = OT_ICMP6_TYPE_PARAMETER_PROBLEM, ///< Parameter Problem
            kTypeEchoRequest      = OT_ICMP6_TYPE_ECHO_REQUEST,      ///< Echo Request
            kTypeEchoReply        = OT_ICMP6_TYPE_ECHO_REPLY,        ///< Echo Reply
            kTypeRouterSolicit    = OT_ICMP6_TYPE_ROUTER_SOLICIT,    ///< Router Solicitation
            kTypeRouterAdvert     = OT_ICMP6_TYPE_ROUTER_ADVERT,     ///< Router Advertisement
        };

        /**
         * ICMPv6 Message Codes
         *
         */
        enum Code : uint8_t
        {
            kCodeDstUnreachNoRoute = OT_ICMP6_CODE_DST_UNREACH_NO_ROUTE, ///< Destination Unreachable No Route
            kCodeFragmReasTimeEx   = OT_ICMP6_CODE_FRAGM_REAS_TIME_EX,   ///< Fragment Reassembly Time Exceeded
        };

        static constexpr uint8_t kTypeFieldOffset     = 0; ///< The byte offset of Type field in ICMP6 header.
        static constexpr uint8_t kCodeFieldOffset     = 1; ///< The byte offset of Code field in ICMP6 header.
        static constexpr uint8_t kChecksumFieldOffset = 2; ///< The byte offset of Checksum field in ICMP6 header.
        static constexpr uint8_t kDataFieldOffset     = 4; ///< The byte offset of Data field in ICMP6 header.

        /**
         * This method indicates whether the ICMPv6 message is an error message.
         *
         * @retval TRUE if the ICMPv6 message is an error message.
         * @retval FALSE if the ICMPv6 message is an informational message.
         *
         */
        bool IsError(void) const { return mType < OT_ICMP6_TYPE_ECHO_REQUEST; }

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

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

        /**
         * This method returns the ICMPv6 message code.
         *
         * @returns The ICMPv6 message code.
         *
         */
        Code GetCode(void) const { return static_cast<Code>(mCode); }

        /**
         * This method sets the ICMPv6 message code.
         *
         * @param[in]  aCode  The ICMPv6 message code.
         *
         */
        void SetCode(Code aCode) { mCode = static_cast<uint8_t>(aCode); }

        /**
         * This method returns the ICMPv6 message checksum.
         *
         * @returns The ICMPv6 message checksum.
         *
         */
        uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); }

        /**
         * This method sets the ICMPv6 message checksum.
         *
         * @param[in]  aChecksum  The ICMPv6 message checksum.
         *
         */
        void SetChecksum(uint16_t aChecksum) { mChecksum = HostSwap16(aChecksum); }

        /**
         * This method returns the ICMPv6 message ID for Echo Requests and Replies.
         *
         * @returns The ICMPv6 message ID.
         *
         */
        uint16_t GetId(void) const { return HostSwap16(mData.m16[0]); }

        /**
         * This method sets the ICMPv6 message ID for Echo Requests and Replies.
         *
         * @param[in]  aId  The ICMPv6 message ID.
         *
         */
        void SetId(uint16_t aId) { mData.m16[0] = HostSwap16(aId); }

        /**
         * This method returns the ICMPv6 message sequence for Echo Requests and Replies.
         *
         * @returns The ICMPv6 message sequence.
         *
         */
        uint16_t GetSequence(void) const { return HostSwap16(mData.m16[1]); }

        /**
         * This method sets the ICMPv6 message sequence for Echo Requests and Replies.
         *
         * @param[in]  aSequence  The ICMPv6 message sequence.
         *
         */
        void SetSequence(uint16_t aSequence) { mData.m16[1] = HostSwap16(aSequence); }
    } OT_TOOL_PACKED_END;

    /**
     * This class implements ICMPv6 message handlers.
     *
     */
    class Handler : public otIcmp6Handler, public LinkedListEntry<Handler>
    {
        friend class Icmp;

    public:
        /**
         * This constructor creates an ICMPv6 message handler.
         *
         * @param[in]  aCallback  A pointer to the function that is called when receiving an ICMPv6 message.
         * @param[in]  aContext   A pointer to arbitrary context information.
         *
         */
        Handler(otIcmp6ReceiveCallback aCallback, void *aContext)
        {
            mReceiveCallback = aCallback;
            mContext         = aContext;
            mNext            = nullptr;
        }

    private:
        void HandleReceiveMessage(Message &aMessage, const MessageInfo &aMessageInfo, const Header &aIcmp6Header)
        {
            mReceiveCallback(mContext, &aMessage, &aMessageInfo, &aIcmp6Header);
        }
    };

    /**
     * This constructor initializes the object.
     *
     * @param[in]  aInstance A reference to the OpenThread instance.
     *
     */
    explicit Icmp(Instance &aInstance);

    /**
     * This method returns a new ICMP message with sufficient header space reserved.
     *
     * @param[in]  aReserved  The number of header bytes to reserve after the ICMP header.
     *
     * @returns A pointer to the message or `nullptr` if no buffers are available.
     *
     */
    Message *NewMessage(uint16_t aReserved);

    /**
     * This method registers ICMPv6 handler.
     *
     * @param[in]  aHandler  A reference to the ICMPv6 handler.
     *
     * @retval kErrorNone     Successfully registered the ICMPv6 handler.
     * @retval kErrorAlready  The ICMPv6 handler is already registered.
     *
     */
    Error RegisterHandler(Handler &aHandler);

    /**
     * This method sends an ICMPv6 Echo Request message.
     *
     * @param[in]  aMessage      A reference to the Echo Request payload.
     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
     * @param[in]  aIdentifier   An identifier to aid in matching Echo Replies to this Echo Request.
     *                           May be zero.
     *
     * @retval kErrorNone     Successfully enqueued the ICMPv6 Echo Request message.
     * @retval kErrorNoBufs   Insufficient buffers available to generate an ICMPv6 Echo Request message.
     *
     */
    Error SendEchoRequest(Message &aMessage, const MessageInfo &aMessageInfo, uint16_t aIdentifier);

    /**
     * This method sends an ICMPv6 error message.
     *
     * @param[in]  aType         The ICMPv6 message type.
     * @param[in]  aCode         The ICMPv6 message code.
     * @param[in]  aMessageInfo  A reference to the message info.
     * @param[in]  aMessage      The error-causing IPv6 message.
     *
     * @retval kErrorNone     Successfully enqueued the ICMPv6 error message.
     * @retval kErrorNoBufs   Insufficient buffers available.
     *
     */
    Error SendError(Header::Type aType, Header::Code aCode, const MessageInfo &aMessageInfo, const Message &aMessage);

    /**
     * This method sends an ICMPv6 error message.
     *
     * @param[in]  aType         The ICMPv6 message type.
     * @param[in]  aCode         The ICMPv6 message code.
     * @param[in]  aMessageInfo  A reference to the message info.
     * @param[in]  aHeaders      The parsed headers from the error-causing IPv6 message.
     *
     * @retval kErrorNone     Successfully enqueued the ICMPv6 error message.
     * @retval kErrorNoBufs   Insufficient buffers available.
     *
     */
    Error SendError(Header::Type aType, Header::Code aCode, const MessageInfo &aMessageInfo, const Headers &aHeaders);

    /**
     * This method handles an ICMPv6 message.
     *
     * @param[in]  aMessage      A reference to the ICMPv6 message.
     * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
     *
     * @retval kErrorNone     Successfully processed the ICMPv6 message.
     * @retval kErrorNoBufs   Insufficient buffers available to generate the reply.
     * @retval kErrorDrop     The ICMPv6 message was invalid and dropped.
     *
     */
    Error HandleMessage(Message &aMessage, MessageInfo &aMessageInfo);

    /**
     * This method indicates whether or not ICMPv6 Echo processing is enabled.
     *
     * @retval TRUE   ICMPv6 Echo processing is enabled.
     * @retval FALSE  ICMPv6 Echo processing is disabled.
     *
     */
    otIcmp6EchoMode GetEchoMode(void) const { return mEchoMode; }

    /**
     * Sets the ICMPv6 echo mode.
     *
     * @param[in]  aMode  The ICMPv6 echo mode.
     *
     */
    void SetEchoMode(otIcmp6EchoMode aMode) { mEchoMode = aMode; }

    /**
     * This method indicates whether or not the ICMPv6 Echo Request should be handled.
     *
     * @retval TRUE if OpenThread should respond with an ICMPv6 Echo Reply.
     * @retval FALSE if OpenThread should not respond with an ICMPv6 Echo Reply.
     *
     */
    bool ShouldHandleEchoRequest(const MessageInfo &aMessageInfo);

    /**
     * This method returns the ICMPv6 Echo sequence number.
     *
     * @returns The sequence number of the next ICMPv6 Echo request.
     *
     */
    uint16_t GetEchoSequence(void) const { return mEchoSequence; }

private:
    Error HandleEchoRequest(Message &aRequestMessage, const MessageInfo &aMessageInfo);

    LinkedList<Handler> mHandlers;

    uint16_t        mEchoSequence;
    otIcmp6EchoMode mEchoMode;
};

/**
 * @}
 *
 */

} // namespace Ip6

DefineCoreType(otIcmp6Header, Ip6::Icmp::Header);
DefineCoreType(otIcmp6Handler, Ip6::Icmp::Handler);

} // namespace ot

#endif // ICMP6_HPP_
