/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    All rights reserved.
 *
 *    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 objects for a CHIP IM Invoke Command Sender
 *
 */

#pragma once

#include <type_traits>

#include "CommandSenderLegacyCallback.h"

#include <app/CommandPathParams.h>
#include <app/MessageDef/InvokeRequestMessage.h>
#include <app/MessageDef/InvokeResponseMessage.h>
#include <app/MessageDef/StatusIB.h>
#include <app/data-model/Encode.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/Optional.h>
#include <lib/core/TLVDebug.h>
#include <lib/support/BitFlags.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/ExchangeHolder.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <protocols/Protocols.h>
#include <system/SystemPacketBuffer.h>
#include <system/TLVPacketBufferBackingStore.h>

#define COMMON_STATUS_SUCCESS 0

namespace chip {
namespace app {

class CommandSender final : public Messaging::ExchangeDelegate
{
public:
    // CommandSender::ExtendableCallback::OnResponse is public SDK API, so we cannot break
    // source compatibility for it. To allow for additional values to be added at a future
    // time without constantly changing the function's declaration parameter list, we are
    // defining the struct ResponseData and adding that to the parameter list to allow for
    // future extendability.
    struct ResponseData
    {
        // The command path field in invoke command response.
        const ConcreteCommandPath & path;
        // The status of the command. It can be any success status, including possibly a cluster-specific one.
        // If `data` is not null, statusIB will always be a generic SUCCESS status with no-cluster specific
        // information.
        const StatusIB & statusIB;
        // The command data, will be nullptr if the server returns a StatusIB.
        TLV::TLVReader * data;
        // Reference for the command. This should be associated with the reference value sent out in the initial
        // invoke request.
        Optional<uint16_t> commandRef;
    };

    // CommandSender::ExtendableCallback::OnError is public SDK API, so we cannot break source
    // compatibility for it. To allow for additional values to be added at a future time
    // without constantly changing the function's declaration parameter list, we are
    // defining the struct ErrorData and adding that to the parameter list
    // to allow for future extendability.
    struct ErrorData
    {
        /**
         * The following errors will be delivered through `error`
         *
         * - CHIP_ERROR_TIMEOUT: A response was not received within the expected response timeout.
         * - CHIP_ERROR_*TLV*: A malformed, non-compliant response was received from the server.
         * - CHIP_ERROR encapsulating a StatusIB: If we got a non-path-specific
         *   status response from the server.  In that case,
         *   StatusIB::InitFromChipError can be used to extract the status.
         * - CHIP_ERROR*: All other cases.
         */
        CHIP_ERROR error;
    };

    /**
     * @brief Callback that is extendable for future features, starting with batch commands
     *
     * The two major differences between ExtendableCallback and Callback are:
     * 1. Path-specific errors go to OnResponse instead of OnError
     *       - Note: Non-path-specific errors still go to OnError.
     * 2. Instead of having new parameters at the end of the arguments list, with defaults,
     *    as functionality expands, a parameter whose type is defined in this header is used
     *    as the argument to the callbacks
     *
     * To support batch commands client must use ExtendableCallback.
     */
    class ExtendableCallback
    {
    public:
        virtual ~ExtendableCallback() = default;

        /**
         * OnResponse will be called for all path specific responses from the server that have been received
         * and processed. Specifically:
         *  - When a status code is received and it is IM::Success, aData will be nullptr.
         *  - When a status code is received and it is IM and/or cluster error, aData will be nullptr.
         *      - These kinds of errors are referred to as path-specific errors.
         *  - When a data response is received, aData will point to a valid TLVReader initialized to point at the struct container
         *    that contains the data payload (callee will still need to open and process the container).
         *
         * The CommandSender object MUST continue to exist after this call is completed. The application shall wait until it
         * receives an OnDone call to destroy the object.
         *
         * @param[in] apCommandSender The command sender object that initiated the command transaction.
         * @param[in] aResponseData   Information pertaining to the response.
         */
        ;
        virtual void OnResponse(CommandSender * commandSender, const ResponseData & aResponseData) {}

        /**
         * OnError will be called when a non-path-specific error occurs *after* a successful call to SendCommandRequest().
         *
         * The CommandSender object MUST continue to exist after this call is completed. The application shall wait until it
         * receives an OnDone call to destroy and free the object.
         *
         * NOTE: Path specific errors do NOT come to OnError, but instead go to OnResponse.
         *
         * @param[in] apCommandSender The command sender object that initiated the command transaction.
         * @param[in] aErrorData      A error data regarding error that occurred.
         */
        virtual void OnError(const CommandSender * apCommandSender, const ErrorData & aErrorData) {}

        /**
         * OnDone will be called when CommandSender has finished all work and is safe to destroy and free the
         * allocated CommandSender object.
         *
         * This function will:
         *      - Always be called exactly *once* for a given CommandSender instance.
         *      - Be called even in error circumstances.
         *      - Only be called after a successful call to SendCommandRequest returns, if SendCommandRequest is used.
         *      - Always be called before a successful return from SendGroupCommandRequest, if SendGroupCommandRequest is used.
         *
         * This function must be implemented to destroy the CommandSender object.
         *
         * @param[in] apCommandSender   The command sender object of the terminated invoke command transaction.
         */
        virtual void OnDone(CommandSender * apCommandSender) = 0;
    };

    // `Callback` exists for legacy purposes. If you are developing a new callback implementation,
    // please use `ExtendableCallback`.
    using Callback = CommandSenderLegacyCallback;

    // SetCommandSenderConfig is a public SDK API, so we cannot break source compatibility
    // for it. By having parameters to that API use this struct instead of individual
    // function arguments, we centralize required changes to one file when adding new
    // funtionality.
    struct ConfigParameters
    {
        ConfigParameters & SetRemoteMaxPathsPerInvoke(uint16_t aRemoteMaxPathsPerInvoke)
        {
            remoteMaxPathsPerInvoke = aRemoteMaxPathsPerInvoke;
            return *this;
        }

        // If remoteMaxPathsPerInvoke is 1, this will allow the CommandSender client to contain only one command and
        // doesn't enforce other batch commands requirements.
        uint16_t remoteMaxPathsPerInvoke = 1;
    };

    // AddRequestData is a public SDK API, so we must maintain source compatibility.
    // Using this struct for API parameters instead of individual parameters allows us
    // to make necessary changes for new functionality in a single location.
    struct AddRequestDataParameters
    {
        // gcc bug requires us to have the constructor below
        // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96645
        AddRequestDataParameters() {}

        AddRequestDataParameters(const Optional<uint16_t> & aTimedInvokeTimeoutMs) : timedInvokeTimeoutMs(aTimedInvokeTimeoutMs) {}

        // When a value is provided for timedInvokeTimeoutMs, this invoke becomes a timed
        // invoke. CommandSender will use the minimum of all provided timeouts for execution.
        const Optional<uint16_t> timedInvokeTimeoutMs;
        // The command reference is required when sending multiple commands. It allows the caller
        // to associate this request with its corresponding response.
        Optional<uint16_t> commandRef;
    };

    // PrepareCommand is a public SDK API, so we must maintain source compatibility.
    // Using this struct for API parameters instead of individual parameters allows us
    // to make necessary changes for new functionality in a single location.
    struct PrepareCommandParameters
    {
        // gcc bug requires us to have the constructor below
        // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96645
        PrepareCommandParameters() {}

        PrepareCommandParameters(const AddRequestDataParameters & aAddRequestDataParam) :
            commandRef(aAddRequestDataParam.commandRef)
        {}

        PrepareCommandParameters & SetStartDataStruct(bool aStartDataStruct)
        {
            startDataStruct = aStartDataStruct;
            return *this;
        }

        PrepareCommandParameters & SetCommandRef(uint16_t aCommandRef)
        {
            commandRef.SetValue(aCommandRef);
            return *this;
        }
        // The command reference is required when sending multiple commands. It allows the caller
        // to associate this request with its corresponding response. We validate the reference
        // early in PrepareCommand, even though it's not used until FinishCommand. This proactive
        // validation helps prevent unnecessary writing an InvokeRequest into the packet that later
        // needs to be undone.
        //
        // Currently, provided commandRefs for the first request must start at 0 and increment by one
        // for each subsequent request. This requirement can be relaxed in the future if a compelling
        // need arises.
        // TODO(#30453): After introducing Request/Response tracking, remove statement above about
        // this currently enforced requirement on commandRefs.
        Optional<uint16_t> commandRef;
        // If the InvokeRequest needs to be in a state with a started data TLV struct container
        bool startDataStruct = false;
    };

    // FinishCommand is a public SDK API, so we must maintain source compatibility.
    // Using this struct for API parameters instead of individual parameters allows us
    // to make necessary changes for new functionality in a single location.
    struct FinishCommandParameters
    {
        // gcc bug requires us to have the constructor below
        // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96645
        FinishCommandParameters() {}

        FinishCommandParameters(const Optional<uint16_t> & aTimedInvokeTimeoutMs) : timedInvokeTimeoutMs(aTimedInvokeTimeoutMs) {}
        FinishCommandParameters(const AddRequestDataParameters & aAddRequestDataParam) :
            timedInvokeTimeoutMs(aAddRequestDataParam.timedInvokeTimeoutMs), commandRef(aAddRequestDataParam.commandRef)
        {}

        FinishCommandParameters & SetEndDataStruct(bool aEndDataStruct)
        {
            endDataStruct = aEndDataStruct;
            return *this;
        }

        FinishCommandParameters & SetCommandRef(uint16_t aCommandRef)
        {
            commandRef.SetValue(aCommandRef);
            return *this;
        }

        // When a value is provided for timedInvokeTimeoutMs, this invoke becomes a timed
        // invoke. CommandSender will use the minimum of all provided timeouts for execution.
        const Optional<uint16_t> timedInvokeTimeoutMs;
        // The command reference is required when sending multiple commands. It allows the caller
        // to associate this request with its corresponding response. This value must be
        // the same as the one provided in PrepareCommandParameters when calling PrepareCommand.
        Optional<uint16_t> commandRef;
        // If InvokeRequest is in a state where the data TLV struct container is currently open
        // and FinishCommand should close it.
        bool endDataStruct = false;
    };

    /*
     * Constructor.
     *
     * The callback passed in has to outlive this CommandSender object.
     * If used in a groups setting, callbacks do not need to be passed.
     * If callbacks are passed the only one that will be called in a group sesttings is the onDone
     */
    CommandSender(Callback * apCallback, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false,
                  bool aSuppressResponse = false);
    CommandSender(ExtendableCallback * apCallback, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false,
                  bool aSuppressResponse = false);
    CommandSender(std::nullptr_t, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false,
                  bool aSuppressResponse = false) :
        CommandSender(static_cast<Callback *>(nullptr), apExchangeMgr, aIsTimedRequest, aSuppressResponse)
    {}
    ~CommandSender();

    /**
     * Enables additional features of CommandSender, for example sending batch commands.
     *
     * In the case of enabling batch commands, once set it ensures that commands contain all
     * required data elements while building the InvokeRequestMessage. This must be called
     * before PrepareCommand.
     *
     * @param [in] aConfigParams contains information to configure CommandSender behavior,
     *                      such as such as allowing a max number of paths per invoke greater than one,
     *                      based on how many paths the remote peer claims to support.
     *
     * @return CHIP_ERROR_INCORRECT_STATE
     *                      If device has previously called `PrepareCommand`.
     * @return CHIP_ERROR_INVALID_ARGUMENT
     *                      Invalid argument value.
     * @return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE
     *                      Device has not enabled CHIP_CONFIG_SENDING_BATCH_COMMANDS_ENABLED.
     */
    CHIP_ERROR SetCommandSenderConfig(ConfigParameters & aConfigParams);

    CHIP_ERROR PrepareCommand(const CommandPathParams & aCommandPathParams, PrepareCommandParameters & aPrepareCommandParams);

    [[deprecated("PrepareCommand should migrate to calling PrepareCommand with PrepareCommandParameters")]] CHIP_ERROR
    PrepareCommand(const CommandPathParams & aCommandPathParams, bool aStartDataStruct = true)
    {
        PrepareCommandParameters prepareCommandParams;
        prepareCommandParams.SetStartDataStruct(aStartDataStruct);
        return PrepareCommand(aCommandPathParams, prepareCommandParams);
    }

    CHIP_ERROR FinishCommand(FinishCommandParameters & aFinishCommandParams);

    [[deprecated("FinishCommand should migrate to calling FinishCommand with FinishCommandParameters")]] CHIP_ERROR
    FinishCommand(bool aEndDataStruct = true)
    {
        FinishCommandParameters finishCommandParams;
        finishCommandParams.SetEndDataStruct(aEndDataStruct);
        return FinishCommand(finishCommandParams);
    }
    [[deprecated("FinishCommand should migrate to calling FinishCommand with FinishCommandParameters")]] CHIP_ERROR
    FinishCommand(const Optional<uint16_t> & aTimedInvokeTimeoutMs)
    {
        FinishCommandParameters finishCommandParams(aTimedInvokeTimeoutMs);
        return FinishCommand(finishCommandParams);
    }

    TLV::TLVWriter * GetCommandDataIBTLVWriter();

    /**
     * API for adding a data request.  The template parameter T is generally
     * expected to be a ClusterName::Commands::CommandName::Type struct, but any
     * object that can be encoded using the DataModel::Encode machinery and
     * exposes the right command id will work.
     *
     * @param [in] aCommandPath  The path of the command being requested.
     * @param [in] aData         The data for the request.
     */
    template <typename CommandDataT, typename std::enable_if_t<!CommandDataT::MustUseTimedInvoke(), int> = 0>
    CHIP_ERROR AddRequestData(const CommandPathParams & aCommandPath, const CommandDataT & aData)
    {
        AddRequestDataParameters addRequestDataParams;
        return AddRequestData(aCommandPath, aData, addRequestDataParams);
    }

    template <typename CommandDataT>
    CHIP_ERROR AddRequestData(const CommandPathParams & aCommandPath, const CommandDataT & aData,
                              AddRequestDataParameters & aAddRequestDataParams)
    {
        VerifyOrReturnError(!CommandDataT::MustUseTimedInvoke() || aAddRequestDataParams.timedInvokeTimeoutMs.HasValue(),
                            CHIP_ERROR_INVALID_ARGUMENT);

        return AddRequestDataInternal(aCommandPath, aData, aAddRequestDataParams);
    }
    template <typename CommandDataT>
    CHIP_ERROR AddRequestData(const CommandPathParams & aCommandPath, const CommandDataT & aData,
                              const Optional<uint16_t> & aTimedInvokeTimeoutMs)
    {
        AddRequestDataParameters addRequestDataParams(aTimedInvokeTimeoutMs);
        return AddRequestData(aCommandPath, aData, addRequestDataParams);
    }

    /**
     * @brief Returns the number of InvokeResponseMessages received.
     *
     * Responses to multiple requests might be split across several InvokeResponseMessages.
     * This function helps track the total count. Primarily for test validation purposes.
     */
    size_t GetInvokeResponseMessageCount();

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    /**
     * Version of AddRequestData that allows sending a message that is
     * guaranteed to fail due to requiring a timed invoke but not providing a
     * timeout parameter.  For use in tests only.
     */
    template <typename CommandDataT>
    CHIP_ERROR TestOnlyAddRequestDataNoTimedCheck(const CommandPathParams & aCommandPath, const CommandDataT & aData,
                                                  AddRequestDataParameters & aAddRequestDataParams)
    {
        return AddRequestDataInternal(aCommandPath, aData, aAddRequestDataParams);
    }

    CHIP_ERROR TestOnlyFinishCommand(FinishCommandParameters & aFinishCommandParams)
    {
        if (mBatchCommandsEnabled)
        {
            VerifyOrReturnError(aFinishCommandParams.commandRef.HasValue(), CHIP_ERROR_INVALID_ARGUMENT);
        }
        return FinishCommandInternal(aFinishCommandParams);
    }

    /**
     * Version of SendCommandRequest that sets the TimedRequest flag but does not send the TimedInvoke
     * action. For use in tests only.
     */
    CHIP_ERROR TestOnlyCommandSenderTimedRequestFlagWithNoTimedInvoke(const SessionHandle & session,
                                                                      Optional<System::Clock::Timeout> timeout = NullOptional);

#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST

private:
    template <typename CommandDataT>
    CHIP_ERROR AddRequestDataInternal(const CommandPathParams & aCommandPath, const CommandDataT & aData,
                                      AddRequestDataParameters & aAddRequestDataParams)
    {
        PrepareCommandParameters prepareCommandParams(aAddRequestDataParams);
        ReturnErrorOnFailure(PrepareCommand(aCommandPath, prepareCommandParams));
        TLV::TLVWriter * writer = GetCommandDataIBTLVWriter();
        VerifyOrReturnError(writer != nullptr, CHIP_ERROR_INCORRECT_STATE);
        ReturnErrorOnFailure(DataModel::Encode(*writer, TLV::ContextTag(CommandDataIB::Tag::kFields), aData));
        FinishCommandParameters finishCommandParams(aAddRequestDataParams);
        return FinishCommand(finishCommandParams);
    }

    CHIP_ERROR FinishCommandInternal(FinishCommandParameters & aFinishCommandParams);

public:
    // Sends a queued up command request to the target encapsulated by the secureSession handle.
    //
    // Upon successful return from this call, all subsequent errors that occur during this interaction
    // will be conveyed through the OnError callback above. In addition, upon completion of work regardless of
    // whether it was successful or not, the OnDone callback will be invoked to indicate completion of work on this
    // object and to indicate to the application that it can destroy and free this object.
    //
    // Applications can, however, destroy this object at any time after this call, except while handling
    // an OnResponse or OnError callback, and it will safely clean-up.
    //
    // If this call returns failure, the callback's OnDone will never be called; the client is responsible
    // for destroying this object on failure.
    //
    // Client can specify the maximum time to wait for response (in milliseconds) via timeout parameter.
    // Default timeout value will be used otherwise.
    //
    CHIP_ERROR SendCommandRequest(const SessionHandle & session, Optional<System::Clock::Timeout> timeout = NullOptional);

    // Sends a queued up group command request to the target encapsulated by the secureSession handle.
    //
    // If this function is successful, it will invoke the OnDone callback before returning to indicate
    // to the application that it can destroy and free this object.
    //
    CHIP_ERROR SendGroupCommandRequest(const SessionHandle & session);

private:
    friend class TestCommandInteraction;

    enum class State : uint8_t
    {
        Idle,                ///< Default state that the object starts out in, where no work has commenced
        AddingCommand,       ///< In the process of adding a command.
        AddedCommand,        ///< A command has been completely encoded and is awaiting transmission.
        AwaitingTimedStatus, ///< Sent a Timed Request and waiting for response.
        AwaitingResponse,    ///< The command has been sent successfully, and we are awaiting invoke response.
        ResponseReceived,    ///< Received a response to our invoke and request and processing the response.
        AwaitingDestruction, ///< The object has completed its work and is awaiting destruction by the application.
    };

    union CallbackHandle
    {
        CallbackHandle(Callback * apCallback) : legacyCallback(apCallback) {}
        CallbackHandle(ExtendableCallback * apExtendableCallback) : extendableCallback(apExtendableCallback) {}
        Callback * legacyCallback;
        ExtendableCallback * extendableCallback;
    };

    void MoveToState(const State aTargetState);
    const char * GetStateStr() const;

    /*
     * Allocates a packet buffer used for encoding an invoke request payload.
     *
     * This can be called multiple times safely, as it will only allocate the buffer once for the lifetime
     * of this object.
     */
    CHIP_ERROR AllocateBuffer();

    // ExchangeDelegate interface implementation.  Private so people won't
    // accidentally call it on us when we're not being treated as an actual
    // ExchangeDelegate.
    CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
                                 System::PacketBufferHandle && aPayload) override;
    void OnResponseTimeout(Messaging::ExchangeContext * apExchangeContext) override;

    //
    // Called internally to signal the completion of all work on this object, gracefully close the
    // exchange (by calling into the base class) and finally, signal to the application that it's
    // safe to release this object.
    //
    void Close();

    /*
     * This forcibly closes the exchange context if a valid one is pointed to. Such a situation does
     * not arise during normal message processing flows that all normally call Close() above. This can only
     * arise due to application-initiated destruction of the object when this object is handling receiving/sending
     * message payloads.
     */
    void Abort();

    CHIP_ERROR ProcessInvokeResponse(System::PacketBufferHandle && payload, bool & moreChunkedMessages);
    CHIP_ERROR ProcessInvokeResponseIB(InvokeResponseIB::Parser & aInvokeResponse);

    void SetTimedInvokeTimeoutMs(const Optional<uint16_t> & aTimedInvokeTimeoutMs);

    // Send our queued-up Invoke Request message.  Assumes the exchange is ready
    // and mPendingInvokeData is populated.
    CHIP_ERROR SendInvokeRequest();

    CHIP_ERROR Finalize(System::PacketBufferHandle & commandPacket);

    CHIP_ERROR SendCommandRequestInternal(const SessionHandle & session, Optional<System::Clock::Timeout> timeout);

    void OnResponseCallback(const ResponseData & aResponseData)
    {
        // mpExtendableCallback and mpCallback are mutually exclusive.
        if (mUseExtendableCallback && mCallbackHandle.extendableCallback)
        {
            mCallbackHandle.extendableCallback->OnResponse(this, aResponseData);
        }
        else if (mCallbackHandle.legacyCallback)
        {
            mCallbackHandle.legacyCallback->OnResponse(this, aResponseData.path, aResponseData.statusIB, aResponseData.data);
        }
    }

    void OnErrorCallback(CHIP_ERROR aError)
    {
        // mpExtendableCallback and mpCallback are mutually exclusive.
        if (mUseExtendableCallback && mCallbackHandle.extendableCallback)
        {
            ErrorData errorData = { aError };
            mCallbackHandle.extendableCallback->OnError(this, errorData);
        }
        else if (mCallbackHandle.legacyCallback)
        {
            mCallbackHandle.legacyCallback->OnError(this, aError);
        }
    }

    void OnDoneCallback()
    {
        // mpExtendableCallback and mpCallback are mutually exclusive.
        if (mUseExtendableCallback && mCallbackHandle.extendableCallback)
        {
            mCallbackHandle.extendableCallback->OnDone(this);
        }
        else if (mCallbackHandle.legacyCallback)
        {
            mCallbackHandle.legacyCallback->OnDone(this);
        }
    }

    Messaging::ExchangeHolder mExchangeCtx;
    CallbackHandle mCallbackHandle;
    Messaging::ExchangeManager * mpExchangeMgr = nullptr;
    InvokeRequestMessage::Builder mInvokeRequestBuilder;
    // TODO Maybe we should change PacketBufferTLVWriter so we can finalize it
    // but have it hold on to the buffer, and get the buffer from it later.
    // Then we could avoid this extra pointer-sized member.
    System::PacketBufferHandle mPendingInvokeData;
    // If mTimedInvokeTimeoutMs has a value, we are expected to do a timed
    // invoke.
    Optional<uint16_t> mTimedInvokeTimeoutMs;
    TLV::TLVType mDataElementContainerType = TLV::kTLVType_NotSpecified;

    chip::System::PacketBufferTLVWriter mCommandMessageWriter;

    uint16_t mInvokeResponseMessageCount = 0;
    uint16_t mFinishedCommandCount       = 0;
    uint16_t mRemoteMaxPathsPerInvoke    = 1;

    State mState                = State::Idle;
    bool mSuppressResponse      = false;
    bool mTimedRequest          = false;
    bool mBufferAllocated       = false;
    bool mBatchCommandsEnabled  = false;
    bool mUseExtendableCallback = false;
};

} // namespace app
} // namespace chip
