/*
 *  Copyright (c) 2023, 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 Mesh Diagnostic module.
 */

#ifndef MESH_DIAG_HPP_
#define MESH_DIAG_HPP_

#include "openthread-core-config.h"

#if OPENTHREAD_CONFIG_MESH_DIAG_ENABLE && OPENTHREAD_FTD

#if !OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE
#error "OPENTHREAD_CONFIG_MESH_DIAG_ENABLE requires OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE"
#endif

#include <openthread/mesh_diag.h>

#include "coap/coap.hpp"
#include "common/callback.hpp"
#include "common/locator.hpp"
#include "common/message.hpp"
#include "common/timer.hpp"
#include "net/ip6_address.hpp"
#include "thread/network_diagnostic.hpp"
#include "thread/network_diagnostic_tlvs.hpp"

struct otMeshDiagIp6AddrIterator
{
};

struct otMeshDiagChildIterator
{
};

namespace ot {
namespace Utils {

/**
 * Implements the Mesh Diagnostics.
 *
 */
class MeshDiag : public InstanceLocator
{
    friend class ot::NetworkDiagnostic::Client;

public:
    static constexpr uint16_t kVersionUnknown = OT_MESH_DIAG_VERSION_UNKNOWN; ///< Unknown version.

    typedef otMeshDiagDiscoverConfig                   DiscoverConfig;              ///< Discovery configuration.
    typedef otMeshDiagDiscoverCallback                 DiscoverCallback;            ///< Discovery callback.
    typedef otMeshDiagQueryChildTableCallback          QueryChildTableCallback;     ///< Query Child Table callback.
    typedef otMeshDiagChildIp6AddrsCallback            ChildIp6AddrsCallback;       ///< Child IPv6 addresses callback.
    typedef otMeshDiagQueryRouterNeighborTableCallback RouterNeighborTableCallback; ///< Neighbor table callback.

    /**
     * Represents an iterator to go over list of IPv6 addresses of a router or an MTD child.
     *
     */
    class Ip6AddrIterator : public otMeshDiagIp6AddrIterator
    {
        friend class MeshDiag;

    public:
        /**
         * Iterates through the discovered IPv6 address of a router.
         *
         * @param[out]     aAddress  A reference to return the next IPv6 address (if any).
         *
         * @retval kErrorNone      Successfully retrieved the next address. @p aAddress is updated.
         * @retval kErrorNotFound  No more address. Reached the end of the list.
         *
         */
        Error GetNextAddress(Ip6::Address &aAddress);

    private:
        Error InitFrom(const Message &aMessage);

        const Message *mMessage;
        uint16_t       mCurOffset;
        uint16_t       mEndOffset;
    };

    /**
     * Represents information about a router in Thread mesh.
     *
     */
    class RouterInfo : public otMeshDiagRouterInfo, public Clearable<RouterInfo>
    {
        friend class MeshDiag;

    private:
        Error ParseFrom(const Message &aMessage);
    };

    /**
     * Represents information about a child in Thread mesh.
     *
     */
    class ChildInfo : public otMeshDiagChildInfo, public Clearable<ChildInfo>
    {
    };

    /**
     * Represents an iterator to go over list of IPv6 addresses of a router.
     *
     */
    class ChildIterator : public otMeshDiagChildIterator
    {
        friend class MeshDiag;

    public:
        /**
         * Iterates through the discovered children of a router.
         *
         * @param[out]     aChildInfo  A reference to return the info for the next child (if any).
         *
         * @retval kErrorNone      Successfully retrieved the next child info. @p aChildInfo is updated.
         * @retval kErrorNotFound  No more child entry. Reached the end of the list.
         *
         */
        Error GetNextChildInfo(ChildInfo &aChildInfo);

    private:
        Error InitFrom(const Message &aMessage, uint16_t aParentRloc16);

        const Message *mMessage;
        uint16_t       mCurOffset;
        uint16_t       mEndOffset;
        uint16_t       mParentRloc16;
    };

    /**
     * Initializes the `MeshDiag` instance.
     *
     * @param[in] aInstance   The OpenThread instance.
     *
     */
    explicit MeshDiag(Instance &aInstance);

    /**
     * Starts network topology discovery.
     *
     * @param[in] aConfig          The configuration to use for discovery (e.g., which items to discover).
     * @param[in] aCallback        The callback to report the discovered routers.
     * @param[in] aContext         A context to pass in @p aCallback.
     *
     * @retval kErrorNone          The network topology discovery started successfully.
     * @retval kErrorBusy          A previous discovery or query request is still ongoing.
     * @retval kErrorInvalidState  Device is not attached.
     * @retval kErrorNoBufs        Could not allocate buffer to send discovery messages.
     *
     */
    Error DiscoverTopology(const DiscoverConfig &aConfig, DiscoverCallback aCallback, void *aContext);

    /**
     * Starts query for child table for a given router.
     *
     * @param[in] aRloc16          The RLOC16 of router to query.
     * @param[in] aCallback        The callback to report the queried child table.
     * @param[in] aContext         A context to pass in @p aCallback.
     *
     * @retval kErrorNone          The query started successfully.
     * @retval kErrorBusy          A previous discovery or query request is still ongoing.
     * @retval kErrorInvalidArgs   The @p aRloc16 is not a valid router RLOC16.
     * @retval kErrorInvalidState  Device is not attached.
     * @retval kErrorNoBufs        Could not allocate buffer to send query messages.
     *
     */
    Error QueryChildTable(uint16_t aRloc16, QueryChildTableCallback aCallback, void *aContext);

    /**
     * Sends a query to a parent to retrieve the IPv6 addresses of all its MTD children.
     *
     * @param[in] aRloc16          The RLOC16 of parent to query.
     * @param[in] aCallback        The callback to report the queried child IPv6 address list.
     * @param[in] aContext         A context to pass in @p aCallback.
     *
     * @retval kErrorNone          The query started successfully.
     * @retval kErrorBusy          A previous discovery or query request is still ongoing.
     * @retval kErrorInvalidArgs   The @p aRloc16 is not a valid  RLOC16.
     * @retval kErrorInvalidState  Device is not attached.
     * @retval kErrorNoBufs        Could not allocate buffer to send query messages.
     *
     */
    Error QueryChildrenIp6Addrs(uint16_t aRloc16, ChildIp6AddrsCallback aCallback, void *aContext);

    /**
     * Starts query for router neighbor table for a given router.
     *
     * @param[in] aRloc16          The RLOC16 of router to query.
     * @param[in] aCallback        The callback to report the queried table.
     * @param[in] aContext         A context to pass in @p aCallback.
     *
     * @retval kErrorNone          The query started successfully.
     * @retval kErrorBusy          A previous discovery or query request is still ongoing.
     * @retval kErrorInvalidArgs   The @p aRloc16 is not a valid router RLOC16.
     * @retval kErrorInvalidState  Device is not attached.
     * @retval kErrorNoBufs        Could not allocate buffer to send query messages.
     *
     */
    Error QueryRouterNeighborTable(uint16_t aRloc16, RouterNeighborTableCallback aCallback, void *aContext);

    /**
     * Cancels an ongoing discovery or query operation if there one, otherwise no action.
     *
     * When ongoing discovery is cancelled, the callback from `DiscoverTopology()` or  `QueryChildTable()` will not be
     * called anymore.
     *
     */
    void Cancel(void);

private:
    typedef ot::NetworkDiagnostic::Tlv Tlv;

    static constexpr uint32_t kResponseTimeout = OPENTHREAD_CONFIG_MESH_DIAG_RESPONSE_TIMEOUT;

    enum State : uint8_t
    {
        kStateIdle,
        kStateDicoverTopology,
        kStateQueryChildTable,
        kStateQueryChildrenIp6Addrs,
        kStateQueryRouterNeighborTable,
    };

    struct DiscoverInfo
    {
        Callback<DiscoverCallback> mCallback;
        Mle::RouterIdSet           mExpectedRouterIdSet;
    };

    struct QueryChildTableInfo
    {
        Callback<QueryChildTableCallback> mCallback;
        uint16_t                          mRouterRloc16;
    };

    struct QueryChildrenIp6AddrsInfo
    {
        Callback<ChildIp6AddrsCallback> mCallback;
        uint16_t                        mParentRloc16;
    };

    struct QueryRouterNeighborTableInfo
    {
        Callback<RouterNeighborTableCallback> mCallback;
        uint16_t                              mRouterRloc16;
    };

    class ChildEntry : public otMeshDiagChildEntry
    {
        friend class MeshDiag;

    private:
        void SetFrom(const NetworkDiagnostic::ChildTlv &aChildTlv);
    };

    class RouterNeighborEntry : public otMeshDiagRouterNeighborEntry
    {
        friend class MeshDiag;

    private:
        void SetFrom(const NetworkDiagnostic::RouterNeighborTlv &aTlv);
    };

    Error SendQuery(uint16_t aRloc16, const uint8_t *aTlvs, uint8_t aTlvsLength);
    void  Finalize(Error aError);
    void  HandleTimer(void);
    bool  HandleDiagnosticGetAnswer(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
    Error ProcessMessage(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint16_t aSenderRloc16);
    bool  ProcessChildTableAnswer(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
    bool  ProcessChildrenIp6AddrsAnswer(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
    bool  ProcessRouterNeighborTableAnswer(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);

    void HandleDiagGetResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult);

    static void HandleDiagGetResponse(void                *aContext,
                                      otMessage           *aMessage,
                                      const otMessageInfo *aMessageInfo,
                                      Error                aResult);

    using TimeoutTimer = TimerMilliIn<MeshDiag, &MeshDiag::HandleTimer>;

    State        mState;
    uint16_t     mExpectedQueryId;
    uint16_t     mExpectedAnswerIndex;
    TimeoutTimer mTimer;

    union
    {
        DiscoverInfo                 mDiscover;
        QueryChildTableInfo          mQueryChildTable;
        QueryChildrenIp6AddrsInfo    mQueryChildrenIp6Addrs;
        QueryRouterNeighborTableInfo mQueryRouterNeighborTable;
    };
};

} // namespace Utils

DefineCoreType(otMeshDiagIp6AddrIterator, Utils::MeshDiag::Ip6AddrIterator);
DefineCoreType(otMeshDiagRouterInfo, Utils::MeshDiag::RouterInfo);
DefineCoreType(otMeshDiagChildInfo, Utils::MeshDiag::ChildInfo);
DefineCoreType(otMeshDiagChildIterator, Utils::MeshDiag::ChildIterator);

} // namespace ot

#endif // OPENTHREAD_CONFIG_MESH_DIAG_ENABLE && OPENTHREAD_FTD

#endif // MESH_DIAG_HPP_
