/*
 *
 *    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/PendingResponseTrackerImpl.h>
#include <app/data-model/EncodableToTLV.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::OnNoResponse 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 NoResponseData and adding that to the parameter list to allow for
    // future extendability.
    struct NoResponseData
    {
        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] commandSender   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) {}

        /**
         * Called for each request that failed to receive a response after the server indicates completion of all requests.
         *
         * This callback may be omitted if clients have alternative ways to track non-responses.
         *
         * 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 commandSender   The CommandSender object that initiated the transaction.
         * @param aNoResponseData Details about the request without a response.
         */
        virtual void OnNoResponse(CommandSender * commandSender, const NoResponseData & aNoResponseData) {}

        /**
         * 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) {}

        AddRequestDataParameters & 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.
        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.
        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;
    };

    class TestOnlyMarker
    {
    };

    /*
     * 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, bool aAllowLargePayload = false);
    CommandSender(std::nullptr_t, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false,
                  bool aSuppressResponse = false, bool aAllowLargePayload = false) :
        CommandSender(static_cast<Callback *>(nullptr), apExchangeMgr, aIsTimedRequest, aSuppressResponse, aAllowLargePayload)
    {}
    CommandSender(ExtendableCallback * apCallback, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false,
                  bool aSuppressResponse = false, bool aAllowLargePayload = false);
    // TODO(#32138): After there is a macro that is always defined for all unit tests, the constructor with
    // TestOnlyMarker should only be compiled if that macro is defined.
    CommandSender(TestOnlyMarker aTestMarker, ExtendableCallback * apCallback, Messaging::ExchangeManager * apExchangeMgr,
                  PendingResponseTracker * apPendingResponseTracker, bool aIsTimedRequest = false, bool aSuppressResponse = false,
                  bool aAllowLargePayload = false) :
        CommandSender(apCallback, apExchangeMgr, aIsTimedRequest, aSuppressResponse, aAllowLargePayload)
    {
        mpPendingResponseTracker = apPendingResponseTracker;
    }
    ~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 batch command support. To enable:
     *               1. Enable the CHIP_CONFIG_COMMAND_SENDER_BUILTIN_SUPPORT_FOR_BATCHED_COMMANDS
     *                  configuration option.
     *               2. Ensure you provide ExtendableCallback.
     */
    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 request data using DataModel::EncodableToTLV.
     *
     * @param [in] aCommandPath The path of the command being requested.
     * @param [in] aEncodable The request data to encode into the
     *             `CommandFields` member of `CommandDataIB`.
     * @param [in] aAddRequestDataParams parameters associated with building the
     *             InvokeRequestMessage that are associated with this request.
     *
     * This API will not fail if this is an untimed invoke but the command provided requires a timed
     * invoke interaction. If the caller wants that to fail before sending the command, they should call
     * the templated version of AddRequestData.
     */
    CHIP_ERROR AddRequestData(const CommandPathParams & aCommandPath, const DataModel::EncodableToTLV & aEncodable,
                              AddRequestDataParameters & aAddRequestDataParams);

    /**
     * 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,
              typename std::enable_if_t<!std::is_base_of_v<DataModel::EncodableToTLV, CommandDataT>, int> = 0>
    CHIP_ERROR AddRequestData(const CommandPathParams & aCommandPath, const CommandDataT & aData,
                              AddRequestDataParameters & aAddRequestDataParams)
    {
        VerifyOrReturnError(!CommandDataT::MustUseTimedInvoke() || aAddRequestDataParams.timedInvokeTimeoutMs.HasValue(),
                            CHIP_ERROR_INVALID_ARGUMENT);

        DataModel::EncodableType<CommandDataT> encodable(aData);
        return AddRequestData(aCommandPath, encodable, 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)
    {
        DataModel::EncodableType<CommandDataT> encodable(aData);
        return AddRequestData(aCommandPath, encodable, 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:
    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.
    };

    /**
     * Class to help backup CommandSender's buffer containing InvokeRequestMessage when adding InvokeRequest
     * in case there is a failure to add InvokeRequest. Intended usage is as follows:
     *  - Allocate RollbackInvokeRequest on the stack.
     *  - Attempt adding InvokeRequest into InvokeRequestMessage buffer.
     *  - If modification is added successfully, call DisableAutomaticRollback() to prevent destructor from
     *    rolling back InvokeReqestMessage.
     *  - If there is an issue adding InvokeRequest, destructor will take care of rolling back
     *    InvokeRequestMessage to previously saved state.
     */
    class RollbackInvokeRequest
    {
    public:
        explicit RollbackInvokeRequest(CommandSender & aCommandSender);
        ~RollbackInvokeRequest();

        /**
         * Disables rolling back to previously saved state for InvokeRequestMessage.
         */
        void DisableAutomaticRollback();

    private:
        CommandSender & mCommandSender;
        TLV::TLVWriter mBackupWriter;
        State mBackupState;
        bool mRollbackInDestructor = false;
    };

    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;

    void FlushNoCommandResponse();
    //
    // 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;

#if CHIP_CONFIG_COMMAND_SENDER_BUILTIN_SUPPORT_FOR_BATCHED_COMMANDS
    PendingResponseTrackerImpl mNonTestPendingResponseTracker;
#endif // CHIP_CONFIG_COMMAND_SENDER_BUILTIN_SUPPORT_FOR_BATCHED_COMMANDS
    PendingResponseTracker * mpPendingResponseTracker = nullptr;

    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;
    bool mAllowLargePayload     = false;
};

} // namespace app
} // namespace chip
