/*
 *
 *    Copyright (c) 2021 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 implements unit tests for CHIP Interaction Model Command Interaction
 *
 */

#include <cinttypes>
#include <optional>

#include <pw_unit_test/framework.h>

#include <app/AppConfig.h>
#include <app/CommandHandlerImpl.h>
#include <app/InteractionModelEngine.h>
#include <app/data-model-provider/ActionReturnStatus.h>
#include <app/data-model/Encode.h>
#include <app/tests/AppTestContext.h>
#include <app/tests/test-interaction-model-api.h>
#include <credentials/GroupDataProviderImpl.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/ErrorStr.h>
#include <lib/core/Optional.h>
#include <lib/core/StringBuilderAdapters.h>
#include <lib/core/TLV.h>
#include <lib/core/TLVDebug.h>
#include <lib/core/TLVUtilities.h>
#include <lib/support/TestGroupData.h>
#include <lib/support/logging/CHIPLogging.h>
#include <lib/support/tests/ExtraPwTestMacros.h>
#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <platform/CHIPDeviceLayer.h>
#include <protocols/interaction_model/Constants.h>
#include <system/SystemPacketBuffer.h>
#include <system/TLVPacketBufferBackingStore.h>

using namespace chip::Protocols;

namespace {

void CheckForInvalidAction(chip::Testing::MessageCapturer & messageLog)
{
    EXPECT_EQ(messageLog.MessageCount(), 1u);
    EXPECT_TRUE(messageLog.IsMessageType(0, chip::Protocols::InteractionModel::MsgType::StatusResponse));
    CHIP_ERROR status;
    EXPECT_EQ(chip::app::StatusResponse::ProcessStatusResponse(std::move(messageLog.MessagePayload(0)), status), CHIP_NO_ERROR);
    EXPECT_EQ(status, CHIP_IM_GLOBAL_STATUS(InvalidAction));
}

} // anonymous namespace

namespace chip {

namespace {
bool isCommandDispatched      = false;
size_t commandDispatchedCount = 0;

bool sendResponse = true;
bool asyncCommand = false;

constexpr EndpointId kTestEndpointId                      = 1;
constexpr ClusterId kTestClusterId                        = 3;
constexpr CommandId kTestCommandIdWithData                = 4;
constexpr CommandId kTestCommandIdNoData                  = 5;
constexpr CommandId kTestCommandIdCommandSpecificResponse = 6;
constexpr CommandId kTestCommandIdFillResponseMessage     = 7;
constexpr CommandId kTestCommandIdIgnoreCommandFields     = 8;
constexpr CommandId kTestNonExistCommandId                = 0;

const app::CommandSender::TestOnlyMarker kCommandSenderTestOnlyMarker;

class SimpleTLVPayload : public app::DataModel::EncodableToTLV
{
public:
    CHIP_ERROR EncodeTo(TLV::TLVWriter & aWriter, TLV::Tag aTag) const override
    {
        TLV::TLVType outerType;
        ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outerType));
        ReturnErrorOnFailure(aWriter.PutBoolean(chip::TLV::ContextTag(1), true));
        return aWriter.EndContainer(outerType);
    }
};

const chip::Testing::MockNodeConfig & TestMockNodeConfig()
{
    using namespace chip::app;
    using namespace chip::Testing;
    using namespace chip::app::Clusters::Globals::Attributes;

    // clang-format off
    static const MockNodeConfig config({
        MockEndpointConfig(chip::kTestEndpointId, {
            MockClusterConfig(Clusters::Identify::Id, {
                ClusterRevision::Id, FeatureMap::Id,
            },
            {},      // events
            {
                kTestCommandIdWithData,
                kTestCommandIdNoData,
                kTestCommandIdCommandSpecificResponse,
                kTestCommandIdFillResponseMessage,
                kTestCommandIdIgnoreCommandFields,
            }, // accepted commands
            {} // generated commands
          ),
        }),
    });
    // clang-format on
    return config;
}

} // namespace

namespace app {

CommandHandler::Handle asyncCommandHandle;

enum class ForcedSizeBufferLengthHint
{
    kSizeBetween0and255,
    kSizeGreaterThan255,
};

class ForcedSizeBuffer : public app::DataModel::EncodableToTLV
{
public:
    ForcedSizeBuffer(uint32_t size)
    {
        if (mBuffer.Alloc(size))
        {
            // No significance with using 0x12, just using a value.
            memset(mBuffer.Get(), 0x12, size);
        }
    }

    // No significance with using 0x12 as the CommandId, just using a value.
    static constexpr chip::CommandId GetCommandId() { return 0x12; }

    CHIP_ERROR EncodeTo(TLV::TLVWriter & aWriter, TLV::Tag aTag) const override
    {
        VerifyOrReturnError(mBuffer, CHIP_ERROR_NO_MEMORY);

        TLV::TLVType outerContainerType;
        ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outerContainerType));
        ReturnErrorOnFailure(app::DataModel::Encode(aWriter, TLV::ContextTag(1), ByteSpan(mBuffer.Get(), mBuffer.AllocatedSize())));
        return aWriter.EndContainer(outerContainerType);
    }

private:
    chip::Platform::ScopedMemoryBufferWithSize<uint8_t> mBuffer;
};

class FillTLVBuffer : public app::DataModel::EncodableToTLV
{
public:
    CHIP_ERROR EncodeTo(TLV::TLVWriter & aWriter, TLV::Tag aTag) const override
    {
        TLV::TLVType outerContainerType;
        ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outerContainerType));

        size_t remaining_length = aWriter.GetRemainingFreeLength();
        // Caller will still will need 1 byte for EndOfCommandDataIB and 1 byte for EndOfInvokeResponseIB
        constexpr size_t kReserveForCallersFinishCommand = 1 + 1;
        // Overhead include 1 control byte, 1 byte for ContextTag, 2 bytes for length, 1 byte for end container.
        constexpr size_t kReservedOverhead = 1 + 1 + 2 + 1 + kReserveForCallersFinishCommand;
        // kReservedOverhead assumes that the length we will be writing is over 255 as this will require an extra byte.
        constexpr size_t kMinimumExpectedLengthToWrite = kReservedOverhead + 255;
        VerifyOrReturnError(remaining_length > kMinimumExpectedLengthToWrite, CHIP_ERROR_INTERNAL);
        remaining_length = remaining_length - kReservedOverhead;
        chip::Platform::ScopedMemoryBufferWithSize<uint8_t> buf;
        buf.Alloc(remaining_length);
        VerifyOrReturnError(buf, CHIP_ERROR_NO_MEMORY);

        // No significance with using 0x12, just using a value.
        memset(buf.Get(), 0x12, remaining_length);

        ReturnErrorOnFailure(app::DataModel::Encode(aWriter, TLV::ContextTag(1), ByteSpan(buf.Get(), buf.AllocatedSize())));
        return aWriter.EndContainer(outerContainerType);
    }
};

struct Fields
{
    static constexpr chip::CommandId GetCommandId() { return 4; }
    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
    {
        TLV::TLVType outerContainerType;
        ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outerContainerType));
        ReturnErrorOnFailure(aWriter.PutBoolean(TLV::ContextTag(1), true));
        return aWriter.EndContainer(outerContainerType);
    }
};

struct BadFields
{
    static constexpr chip::CommandId GetCommandId() { return 4; }
    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
    {
        TLV::TLVType outerContainerType;
        uint8_t data[36] = { 0 };
        ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outerContainerType));
        // Just encode something bad to return a failure state here.
        for (uint8_t i = 1; i < UINT8_MAX; i++)
        {
            ReturnErrorOnFailure(app::DataModel::Encode(aWriter, TLV::ContextTag(i), ByteSpan(data)));
        }
        return aWriter.EndContainer(outerContainerType);
    }
};

static Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aRequestCommandPath)
{
    // Mock cluster catalog, only support commands on one cluster on one endpoint.
    if (aRequestCommandPath.mEndpointId != kTestEndpointId)
    {
        return Protocols::InteractionModel::Status::UnsupportedEndpoint;
    }

    if (aRequestCommandPath.mClusterId != kTestClusterId)
    {
        return Protocols::InteractionModel::Status::UnsupportedCluster;
    }

    if (aRequestCommandPath.mCommandId == kTestNonExistCommandId)
    {
        return Protocols::InteractionModel::Status::UnsupportedCommand;
    }

    return Protocols::InteractionModel::Status::Success;
}

void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPath, chip::TLV::TLVReader & aReader,
                                  CommandHandler * apCommandObj)
{
    ChipLogDetail(Controller, "Received Cluster Command: Endpoint=%x Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI,
                  aRequestCommandPath.mEndpointId, ChipLogValueMEI(aRequestCommandPath.mClusterId),
                  ChipLogValueMEI(aRequestCommandPath.mCommandId));

    // Duplicate what our normal command-field-decode code does, in terms of
    // checking for a struct and then entering it before getting the fields.
    if (aReader.GetType() != TLV::kTLVType_Structure)
    {
        apCommandObj->AddStatus(aRequestCommandPath, Protocols::InteractionModel::Status::InvalidAction);
        return;
    }

    TLV::TLVType outerContainerType;
    EXPECT_EQ(aReader.EnterContainer(outerContainerType), CHIP_NO_ERROR);

    CHIP_ERROR err = aReader.Next();
    if (aRequestCommandPath.mCommandId == kTestCommandIdNoData)
    {
        EXPECT_EQ(err, CHIP_ERROR_END_OF_TLV);
    }
    else if (aRequestCommandPath.mCommandId == kTestCommandIdIgnoreCommandFields)
    {
        EXPECT_EQ(err, CHIP_NO_ERROR);
    }
    else
    {
        EXPECT_EQ(err, CHIP_NO_ERROR);
        EXPECT_EQ(aReader.GetTag(), TLV::ContextTag(1));

        bool val;
        EXPECT_EQ(aReader.Get(val), CHIP_NO_ERROR);
        EXPECT_TRUE(val);
    }

    EXPECT_EQ(aReader.ExitContainer(outerContainerType), CHIP_NO_ERROR);

    if (asyncCommand)
    {
        asyncCommandHandle = apCommandObj;
        asyncCommand       = false;
    }

    if (sendResponse)
    {
        if (aRequestCommandPath.mCommandId == kTestCommandIdNoData || aRequestCommandPath.mCommandId == kTestCommandIdWithData)
        {
            apCommandObj->AddStatus(aRequestCommandPath, Protocols::InteractionModel::Status::Success);
        }
        else if (aRequestCommandPath.mCommandId == kTestCommandIdFillResponseMessage)
        {
            FillTLVBuffer response;
            EXPECT_EQ(apCommandObj->AddResponseData(aRequestCommandPath, aRequestCommandPath.mCommandId, response), CHIP_NO_ERROR);
        }
        else
        {
            SimpleTLVPayload payloadWriter;
            apCommandObj->AddResponse(aRequestCommandPath, aRequestCommandPath.mCommandId, payloadWriter);
        }
    }

    chip::isCommandDispatched = true;
    commandDispatchedCount++;
}

class MockCommandSenderCallback : public CommandSender::Callback
{
public:
    void OnResponse(chip::app::CommandSender * apCommandSender, const chip::app::ConcreteCommandPath & aPath,
                    const chip::app::StatusIB & aStatus, chip::TLV::TLVReader * aData) override
    {
        IgnoreUnusedVariable(apCommandSender);
        IgnoreUnusedVariable(aData);
        ChipLogDetail(Controller, "Received Cluster Command: Cluster=%" PRIx32 " Command=%" PRIx32 " Endpoint=%x", aPath.mClusterId,
                      aPath.mCommandId, aPath.mEndpointId);
        onResponseCalledTimes++;
    }
    void OnError(const chip::app::CommandSender * apCommandSender, CHIP_ERROR aError) override
    {
        ChipLogError(Controller, "OnError happens with %" CHIP_ERROR_FORMAT, aError.Format());
        mError = aError;
        onErrorCalledTimes++;
        mError = aError;
    }
    void OnDone(chip::app::CommandSender * apCommandSender) override { onFinalCalledTimes++; }

    void ResetCounter()
    {
        onResponseCalledTimes = 0;
        onErrorCalledTimes    = 0;
        onFinalCalledTimes    = 0;
    }

    int onResponseCalledTimes = 0;
    int onErrorCalledTimes    = 0;
    int onFinalCalledTimes    = 0;
    CHIP_ERROR mError         = CHIP_NO_ERROR;
} mockCommandSenderDelegate;

class MockCommandSenderExtendableCallback : public CommandSender::ExtendableCallback
{
public:
    void OnResponse(CommandSender * apCommandSender, const CommandSender::ResponseData & aResponseData) override
    {
        IgnoreUnusedVariable(apCommandSender);
        ChipLogDetail(Controller, "Received response for command: Cluster=%" PRIx32 " Command=%" PRIx32 " Endpoint=%x",
                      aResponseData.path.mClusterId, aResponseData.path.mCommandId, aResponseData.path.mEndpointId);
        onResponseCalledTimes++;
    }
    void OnNoResponse(CommandSender * commandSender, const CommandSender::NoResponseData & aNoResponseData) override
    {
        ChipLogError(Controller, "NoResponse received for command associated with CommandRef %u", aNoResponseData.commandRef);
        onNoResponseCalledTimes++;
    }
    void OnError(const CommandSender * apCommandSender, const CommandSender::ErrorData & aErrorData) override
    {
        ChipLogError(Controller, "OnError happens with %" CHIP_ERROR_FORMAT, aErrorData.error.Format());
        mError = aErrorData.error;
        onErrorCalledTimes++;
    }
    void OnDone(CommandSender * apCommandSender) override { onFinalCalledTimes++; }

    void ResetCounter()
    {
        onResponseCalledTimes   = 0;
        onNoResponseCalledTimes = 0;
        onErrorCalledTimes      = 0;
        onFinalCalledTimes      = 0;
    }

    int onResponseCalledTimes   = 0;
    int onNoResponseCalledTimes = 0;
    int onErrorCalledTimes      = 0;
    int onFinalCalledTimes      = 0;
    CHIP_ERROR mError           = CHIP_NO_ERROR;
} mockCommandSenderExtendedDelegate;

class MockCommandResponder : public CommandHandlerExchangeInterface
{
public:
    Messaging::ExchangeContext * GetExchangeContext() const override { return nullptr; }
    void HandlingSlowCommand() override {}
    Access::SubjectDescriptor GetSubjectDescriptor() const override { return Access::SubjectDescriptor(); }
    FabricIndex GetAccessingFabricIndex() const override { return kUndefinedFabricIndex; }

    Optional<GroupId> GetGroupId() const override { return NullOptional; }

    void AddInvokeResponseToSend(System::PacketBufferHandle && aPacket) override { mChunks.AddToEnd(std::move(aPacket)); }
    void ResponseDropped() override { mResponseDropped = true; }

    size_t GetCommandResponseMaxBufferSize() override { return kMaxSecureSduLengthBytes; }

    System::PacketBufferHandle mChunks;
    bool mResponseDropped = false;
};

class MockCommandHandlerCallback : public CommandHandlerImpl::Callback
{
public:
    void OnDone(CommandHandlerImpl & apCommandHandler) final { onFinalCalledTimes++; }
    void DispatchCommand(CommandHandlerImpl & apCommandObj, const ConcreteCommandPath & aCommandPath,
                         TLV::TLVReader & apPayload) final
    {
        DispatchSingleClusterCommand(aCommandPath, apPayload, &apCommandObj);
    }

    Protocols::InteractionModel::Status ValidateCommandCanBeDispatched(const DataModel::InvokeRequest & request) override
    {
        using Protocols::InteractionModel::Status;

        Status status = ServerClusterCommandExists(request.path);
        if (status != Status::Success)
        {
            return status;
        }

        // NOTE: IM does more validation here, however for now we do minimal options
        //       to pass the test.

        return Status::Success;
    }

    void ResetCounter() { onFinalCalledTimes = 0; }

    int onFinalCalledTimes = 0;
} mockCommandHandlerDelegate;

class TestCommandInteractionModel : public TestImCustomDataModel
{
public:
    static TestCommandInteractionModel * Instance()
    {
        static TestCommandInteractionModel instance;
        return &instance;
    }

    TestCommandInteractionModel() = default;

    std::optional<DataModel::ActionReturnStatus> InvokeCommand(const DataModel::InvokeRequest & request,
                                                               chip::TLV::TLVReader & input_arguments,
                                                               CommandHandler * handler) override
    {
        DispatchSingleClusterCommand(request.path, input_arguments, handler);
        return std::nullopt; // handler status is set by the dispatch
    }
};

namespace {
constexpr uint16_t kMaxGroupsPerFabric    = 5;
constexpr uint16_t kMaxGroupKeysPerFabric = 8;

chip::TestPersistentStorageDelegate gTestStorage;
chip::Crypto::DefaultSessionKeystore gSessionKeystore;
chip::Credentials::GroupDataProviderImpl gGroupsProvider(kMaxGroupsPerFabric, kMaxGroupKeysPerFabric);
} // namespace

class TestCommandInteraction : public chip::Testing::AppContext
{
public:
    void SetUp() override
    {
        AppContext::SetUp();

        gTestStorage.ClearStorage();
        gGroupsProvider.SetStorageDelegate(&gTestStorage);
        gGroupsProvider.SetSessionKeystore(&gSessionKeystore);
        ASSERT_EQ(gGroupsProvider.Init(), CHIP_NO_ERROR);
        chip::Credentials::SetGroupDataProvider(&gGroupsProvider);

        uint8_t buf[sizeof(chip::CompressedFabricId)];
        chip::MutableByteSpan span(buf);
        ASSERT_EQ(GetBobFabric()->GetCompressedFabricIdBytes(span), CHIP_NO_ERROR);
        ASSERT_EQ(chip::GroupTesting::InitData(&gGroupsProvider, GetBobFabricIndex(), span), CHIP_NO_ERROR);

        mOldProvider = InteractionModelEngine::GetInstance()->SetDataModelProvider(TestCommandInteractionModel::Instance());
        chip::Testing::SetMockNodeConfig(TestMockNodeConfig());
    }

    void TearDown() override
    {
        chip::Credentials::GroupDataProvider * provider = chip::Credentials::GetGroupDataProvider();
        if (provider != nullptr)
        {
            provider->Finish();
        }
        chip::Credentials::SetGroupDataProvider(nullptr);

        chip::Testing::ResetMockNodeConfig();
        InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider);
        AppContext::TearDown();
    }

    static size_t GetNumActiveCommandResponderObjects()
    {
        return chip::app::InteractionModelEngine::GetInstance()->mCommandResponderObjs.Allocated();
    }

    void TestCommandInvalidMessage1();
    void TestCommandInvalidMessage2();
    void TestCommandInvalidMessage3();
    void TestCommandInvalidMessage4();
    void TestCommandSender_WithSendCommand();
    void TestCommandSender_WithProcessReceivedMsg();
    void TestCommandSender_ExtendableApiWithProcessReceivedMsg();
    void TestCommandSender_ExtendableApiWithProcessReceivedMsgContainingInvalidCommandRef();
    void TestCommandSender_ValidateSecondLargeAddRequestDataRollbacked();
    void TestCommandHandler_WithoutResponderCallingAddStatus();
    void TestCommandHandler_WithoutResponderCallingAddResponse();
    void TestCommandHandler_WithoutResponderCallingDirectPrepareFinishCommandApis();
    void TestCommandHandler_RejectsMultipleCommandsWithIdenticalCommandRef();
    void TestCommandHandler_RejectMultipleCommandsWhenHandlerOnlySupportsOne();
    void TestCommandHandler_AcceptMultipleCommands();
    void TestCommandHandler_FillUpInvokeResponseMessageWhereSecondResponseIsStatusResponse();
    void TestCommandHandler_FillUpInvokeResponseMessageWhereSecondResponseIsDataResponsePrimative();
    void TestCommandHandler_FillUpInvokeResponseMessageWhereSecondResponseIsDataResponse();
    void TestCommandHandler_ReleaseWithExchangeClosed();
    void TestCommandHandler_GetExchangeContextWhenAsync();

    /**
     * With the introduction of batch invoke commands, CommandHandler keeps track of incoming
     * ConcreteCommandPath and the associated CommandRefs. These are normally populated
     * as part of OnInvokeCommandRequest from the incoming request. For some unit tests where
     * we want to test APIs that cluster code uses, we need to inject entries into the
     * CommandPathRegistry directly.
     */
    class CommandHandlerWithUnrespondedCommand : public app::CommandHandlerImpl
    {
    public:
        CommandHandlerWithUnrespondedCommand(CommandHandlerImpl::Callback * apCallback,
                                             const ConcreteCommandPath & aRequestCommandPath, const Optional<uint16_t> & aRef) :
            CommandHandlerImpl(apCallback)
        {
            EXPECT_SUCCESS(GetCommandPathRegistry().Add(aRequestCommandPath, aRef.std_optional()));
            SetExchangeInterface(&mMockCommandResponder);
        }
        MockCommandResponder mMockCommandResponder;

        using app::CommandHandler::AddResponse;
    };

    // Generate an invoke request.  If aCommandId is kTestCommandIdWithData, a
    // payload will be included.  Otherwise no payload will be included.
    static void GenerateInvokeRequest(System::PacketBufferHandle & aPayload, bool aIsTimedRequest, CommandId aCommandId,
                                      ClusterId aClusterId = kTestClusterId, EndpointId aEndpointId = kTestEndpointId);
    // Generate an invoke response.  If aCommandId is kTestCommandIdWithData, a
    // payload will be included.  Otherwise no payload will be included.
    static void GenerateInvokeResponse(System::PacketBufferHandle & aPayload, CommandId aCommandId,
                                       ClusterId aClusterId = kTestClusterId, EndpointId aEndpointId = kTestEndpointId,
                                       std::optional<uint16_t> aCommandRef = std::nullopt);
    static void AddInvokeRequestData(CommandSender * apCommandSender, CommandId aCommandId = kTestCommandIdWithData);
    static void AddInvalidInvokeRequestData(CommandSender * apCommandSender, CommandId aCommandId = kTestCommandIdWithData);
    static void AddInvokeResponseData(CommandHandler * apCommandHandler, bool aNeedStatusCode,
                                      CommandId aResponseCommandId = kTestCommandIdWithData,
                                      CommandId aRequestCommandId  = kTestCommandIdWithData);
    static uint32_t GetAddResponseDataOverheadSizeForPath(const ConcreteCommandPath & aRequestCommandPath,
                                                          ForcedSizeBufferLengthHint aBufferSizeHint);
    static void FillCurrentInvokeResponseBuffer(CommandHandlerImpl * apCommandHandler,
                                                const ConcreteCommandPath & aRequestCommandPath, uint32_t aSizeToLeaveInBuffer);
    static void ValidateCommandHandlerEncodeInvokeResponseMessage(bool aNeedStatusCode);

protected:
    chip::app::DataModel::Provider * mOldProvider = nullptr;
};

class TestExchangeDelegate : public Messaging::ExchangeDelegate
{
    CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
                                 System::PacketBufferHandle && payload) override
    {
        return CHIP_NO_ERROR;
    }

    void OnResponseTimeout(Messaging::ExchangeContext * ec) override {}
};

CommandPathParams MakeTestCommandPath(CommandId aCommandId = kTestCommandIdWithData)
{
    return CommandPathParams(kTestEndpointId, 0, kTestClusterId, aCommandId, (chip::app::CommandPathFlags::kEndpointIdValid));
}

void TestCommandInteraction::GenerateInvokeRequest(System::PacketBufferHandle & aPayload, bool aIsTimedRequest,
                                                   CommandId aCommandId, ClusterId aClusterId, EndpointId aEndpointId)

{
    InvokeRequestMessage::Builder invokeRequestMessageBuilder;
    System::PacketBufferTLVWriter writer;
    writer.Init(std::move(aPayload));

    EXPECT_EQ(invokeRequestMessageBuilder.Init(&writer), CHIP_NO_ERROR);

    invokeRequestMessageBuilder.SuppressResponse(true).TimedRequest(aIsTimedRequest);
    InvokeRequests::Builder & invokeRequests = invokeRequestMessageBuilder.CreateInvokeRequests();
    ASSERT_EQ(invokeRequestMessageBuilder.GetError(), CHIP_NO_ERROR);

    CommandDataIB::Builder & commandDataIBBuilder = invokeRequests.CreateCommandData();
    EXPECT_EQ(invokeRequests.GetError(), CHIP_NO_ERROR);

    CommandPathIB::Builder & commandPathBuilder = commandDataIBBuilder.CreatePath();
    EXPECT_EQ(commandDataIBBuilder.GetError(), CHIP_NO_ERROR);

    EXPECT_SUCCESS(commandPathBuilder.EndpointId(aEndpointId).ClusterId(aClusterId).CommandId(aCommandId).EndOfCommandPathIB());
    EXPECT_EQ(commandPathBuilder.GetError(), CHIP_NO_ERROR);

    if (aCommandId == kTestCommandIdWithData)
    {
        chip::TLV::TLVWriter * pWriter = commandDataIBBuilder.GetWriter();
        chip::TLV::TLVType dummyType   = chip::TLV::kTLVType_NotSpecified;
        EXPECT_EQ(pWriter->StartContainer(chip::TLV::ContextTag(chip::to_underlying(CommandDataIB::Tag::kFields)),
                                          chip::TLV::kTLVType_Structure, dummyType),
                  CHIP_NO_ERROR);

        EXPECT_EQ(pWriter->PutBoolean(chip::TLV::ContextTag(1), true), CHIP_NO_ERROR);

        EXPECT_EQ(pWriter->EndContainer(dummyType), CHIP_NO_ERROR);
    }

    EXPECT_SUCCESS(commandDataIBBuilder.EndOfCommandDataIB());
    EXPECT_EQ(commandDataIBBuilder.GetError(), CHIP_NO_ERROR);

    EXPECT_SUCCESS(invokeRequests.EndOfInvokeRequests());
    EXPECT_EQ(invokeRequests.GetError(), CHIP_NO_ERROR);

    EXPECT_SUCCESS(invokeRequestMessageBuilder.EndOfInvokeRequestMessage());
    ASSERT_EQ(invokeRequestMessageBuilder.GetError(), CHIP_NO_ERROR);

    EXPECT_EQ(writer.Finalize(&aPayload), CHIP_NO_ERROR);
}

void TestCommandInteraction::GenerateInvokeResponse(System::PacketBufferHandle & aPayload, CommandId aCommandId,
                                                    ClusterId aClusterId, EndpointId aEndpointId,
                                                    std::optional<uint16_t> aCommandRef)

{
    InvokeResponseMessage::Builder invokeResponseMessageBuilder;
    System::PacketBufferTLVWriter writer;
    writer.Init(std::move(aPayload));

    EXPECT_EQ(invokeResponseMessageBuilder.Init(&writer), CHIP_NO_ERROR);

    invokeResponseMessageBuilder.SuppressResponse(true);
    InvokeResponseIBs::Builder & invokeResponses = invokeResponseMessageBuilder.CreateInvokeResponses();
    EXPECT_EQ(invokeResponseMessageBuilder.GetError(), CHIP_NO_ERROR);

    InvokeResponseIB::Builder & invokeResponseIBBuilder = invokeResponses.CreateInvokeResponse();
    EXPECT_EQ(invokeResponses.GetError(), CHIP_NO_ERROR);

    CommandDataIB::Builder & commandDataIBBuilder = invokeResponseIBBuilder.CreateCommand();
    EXPECT_EQ(commandDataIBBuilder.GetError(), CHIP_NO_ERROR);

    CommandPathIB::Builder & commandPathBuilder = commandDataIBBuilder.CreatePath();
    EXPECT_EQ(commandDataIBBuilder.GetError(), CHIP_NO_ERROR);

    EXPECT_SUCCESS(commandPathBuilder.EndpointId(aEndpointId).ClusterId(aClusterId).CommandId(aCommandId).EndOfCommandPathIB());
    EXPECT_EQ(commandPathBuilder.GetError(), CHIP_NO_ERROR);

    if (aCommandId == kTestCommandIdWithData)
    {
        chip::TLV::TLVWriter * pWriter = commandDataIBBuilder.GetWriter();
        chip::TLV::TLVType dummyType   = chip::TLV::kTLVType_NotSpecified;

        EXPECT_EQ(pWriter->StartContainer(chip::TLV::ContextTag(chip::to_underlying(CommandDataIB::Tag::kFields)),
                                          chip::TLV::kTLVType_Structure, dummyType),
                  CHIP_NO_ERROR);

        EXPECT_EQ(pWriter->PutBoolean(chip::TLV::ContextTag(1), true), CHIP_NO_ERROR);

        EXPECT_EQ(pWriter->EndContainer(dummyType), CHIP_NO_ERROR);
    }

    if (aCommandRef.has_value())
    {
        EXPECT_EQ(commandDataIBBuilder.Ref(*aCommandRef), CHIP_NO_ERROR);
    }

    EXPECT_SUCCESS(commandDataIBBuilder.EndOfCommandDataIB());
    EXPECT_EQ(commandDataIBBuilder.GetError(), CHIP_NO_ERROR);

    EXPECT_SUCCESS(invokeResponseIBBuilder.EndOfInvokeResponseIB());
    EXPECT_EQ(invokeResponseIBBuilder.GetError(), CHIP_NO_ERROR);

    EXPECT_SUCCESS(invokeResponses.EndOfInvokeResponses());
    EXPECT_EQ(invokeResponses.GetError(), CHIP_NO_ERROR);

    EXPECT_SUCCESS(invokeResponseMessageBuilder.EndOfInvokeResponseMessage());
    EXPECT_EQ(invokeResponseMessageBuilder.GetError(), CHIP_NO_ERROR);

    EXPECT_EQ(writer.Finalize(&aPayload), CHIP_NO_ERROR);
}

void TestCommandInteraction::AddInvokeRequestData(CommandSender * apCommandSender, CommandId aCommandId)
{
    auto commandPathParams = MakeTestCommandPath(aCommandId);

    EXPECT_EQ(apCommandSender->PrepareCommand(commandPathParams), CHIP_NO_ERROR);

    chip::TLV::TLVWriter * writer = apCommandSender->GetCommandDataIBTLVWriter();

    EXPECT_EQ(writer->PutBoolean(chip::TLV::ContextTag(1), true), CHIP_NO_ERROR);
    EXPECT_EQ(apCommandSender->FinishCommand(), CHIP_NO_ERROR);
}

void TestCommandInteraction::AddInvalidInvokeRequestData(CommandSender * apCommandSender, CommandId aCommandId)
{
    auto commandPathParams = MakeTestCommandPath(aCommandId);

    EXPECT_EQ(apCommandSender->PrepareCommand(commandPathParams), CHIP_NO_ERROR);

    chip::TLV::TLVWriter * writer = apCommandSender->GetCommandDataIBTLVWriter();

    EXPECT_EQ(writer->PutBoolean(chip::TLV::ContextTag(1), true), CHIP_NO_ERROR);
    apCommandSender->MoveToState(CommandSender::State::AddedCommand);
}

void TestCommandInteraction::AddInvokeResponseData(CommandHandler * apCommandHandler, bool aNeedStatusCode,
                                                   CommandId aResponseCommandId, CommandId aRequestCommandId)
{
    constexpr EndpointId kTestEndpointId   = 1;
    constexpr ClusterId kTestClusterId     = 3;
    ConcreteCommandPath requestCommandPath = { kTestEndpointId, kTestClusterId, aRequestCommandId };
    if (aNeedStatusCode)
    {
        apCommandHandler->AddStatus(requestCommandPath, Protocols::InteractionModel::Status::Success);
    }
    else
    {
        SimpleTLVPayload payloadWriter;
        EXPECT_EQ(apCommandHandler->AddResponseData(requestCommandPath, aResponseCommandId, payloadWriter), CHIP_NO_ERROR);
    }
}

uint32_t TestCommandInteraction::GetAddResponseDataOverheadSizeForPath(const ConcreteCommandPath & aRequestCommandPath,
                                                                       ForcedSizeBufferLengthHint aBufferSizeHint)
{
    BasicCommandPathRegistry<4> basicCommandPathRegistry;
    MockCommandResponder mockCommandResponder;
    CommandHandlerImpl::TestOnlyOverrides testOnlyOverrides{ &basicCommandPathRegistry, &mockCommandResponder };
    CommandHandlerImpl commandHandler(testOnlyOverrides, &mockCommandHandlerDelegate);
    commandHandler.mReserveSpaceForMoreChunkMessages = true;
    ConcreteCommandPath requestCommandPath1          = { kTestEndpointId, kTestClusterId, kTestCommandIdFillResponseMessage };
    ConcreteCommandPath requestCommandPath2          = { kTestEndpointId, kTestClusterId, kTestCommandIdCommandSpecificResponse };

    EXPECT_EQ(basicCommandPathRegistry.Add(requestCommandPath1, std::make_optional<uint16_t>(static_cast<uint16_t>(1))),
              CHIP_NO_ERROR);

    EXPECT_EQ(basicCommandPathRegistry.Add(requestCommandPath2, std::make_optional<uint16_t>(static_cast<uint16_t>(2))),
              CHIP_NO_ERROR);

    EXPECT_EQ(commandHandler.AllocateBuffer(), CHIP_NO_ERROR);

    uint32_t remainingSizeBefore = commandHandler.mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();

    // When ForcedSizeBuffer exceeds 255, an extra byte is needed for length, affecting the overhead size required by
    // AddResponseData. In order to have this accounted for in overhead calculation we set the length to be 256.
    uint32_t sizeOfForcedSizeBuffer = aBufferSizeHint == ForcedSizeBufferLengthHint::kSizeGreaterThan255 ? 256 : 0;
    ForcedSizeBuffer responseData(sizeOfForcedSizeBuffer);
    EXPECT_EQ(commandHandler.AddResponseData(aRequestCommandPath, responseData.GetCommandId(), responseData), CHIP_NO_ERROR);
    uint32_t remainingSizeAfter = commandHandler.mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();
    uint32_t delta              = remainingSizeBefore - remainingSizeAfter - sizeOfForcedSizeBuffer;

    return delta;
}

void TestCommandInteraction::FillCurrentInvokeResponseBuffer(CommandHandlerImpl * apCommandHandler,
                                                             const ConcreteCommandPath & aRequestCommandPath,
                                                             uint32_t aSizeToLeaveInBuffer)
{
    EXPECT_EQ(apCommandHandler->AllocateBuffer(), CHIP_NO_ERROR);
    uint32_t remainingSize = apCommandHandler->mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();

    // AddResponseData's overhead calculation depends on the size of ForcedSizeBuffer. If the buffer exceeds 255 bytes, an extra
    // length byte is required. Since tests using FillCurrentInvokeResponseBuffer currently end up with sizeToFill > 255, we
    // inform the calculation of this expectation. Nonetheless, we also validate this assumption for correctness.
    ForcedSizeBufferLengthHint bufferSizeHint    = ForcedSizeBufferLengthHint::kSizeGreaterThan255;
    uint32_t overheadSizeNeededForAddingResponse = GetAddResponseDataOverheadSizeForPath(aRequestCommandPath, bufferSizeHint);
    EXPECT_GT(remainingSize, (aSizeToLeaveInBuffer + overheadSizeNeededForAddingResponse));
    uint32_t sizeToFill = remainingSize - aSizeToLeaveInBuffer - overheadSizeNeededForAddingResponse;

    // Validating assumption. If this fails, it means overheadSizeNeededForAddingResponse is likely too large.
    EXPECT_GE(sizeToFill, 256u);

    ForcedSizeBuffer responseData(sizeToFill);
    EXPECT_EQ(apCommandHandler->AddResponseData(aRequestCommandPath, responseData.GetCommandId(), responseData), CHIP_NO_ERROR);
}

void TestCommandInteraction::ValidateCommandHandlerEncodeInvokeResponseMessage(bool aNeedStatusCode)
{
    chip::app::ConcreteCommandPath requestCommandPath(kTestEndpointId, kTestClusterId, kTestCommandIdWithData);
    CommandHandlerWithUnrespondedCommand commandHandler(&mockCommandHandlerDelegate, requestCommandPath,
                                                        /* aRef = */ NullOptional);

    {
        // This simulates how cluster would call CommandHandler APIs synchronously. There would
        // be handle already acquired on the callers behalf.
        CommandHandler::Handle handle(&commandHandler);

        AddInvokeResponseData(&commandHandler, aNeedStatusCode);
    }
    EXPECT_FALSE(commandHandler.mMockCommandResponder.mChunks.IsNull());
}

// Command Sender sends invoke request, command handler drops invoke response, then test injects status response message with
// busy to client, client sends out a status response with invalid action.
TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage1)
{
    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    asyncCommand = false;

    GetLoopback().mSentMessageCount                 = 0;
    GetLoopback().mNumMessagesToDrop                = 1;
    GetLoopback().mNumMessagesToAllowBeforeDropping = 1;
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);
    DrainAndServiceIO();

    EXPECT_EQ(GetLoopback().mSentMessageCount, 2u);
    EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u);

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);

    System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes);
    ASSERT_FALSE(msgBuf.IsNull());
    System::PacketBufferTLVWriter writer;
    writer.Init(std::move(msgBuf));
    StatusResponseMessage::Builder response;
    EXPECT_SUCCESS(response.Init(&writer));
    response.Status(Protocols::InteractionModel::Status::Busy);
    EXPECT_EQ(writer.Finalize(&msgBuf), CHIP_NO_ERROR);

    PayloadHeader payloadHeader;
    payloadHeader.SetExchangeID(0);
    payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::StatusResponse);
    chip::Testing::MessageCapturer messageLog(*this);
    messageLog.mCaptureStandaloneAcks = false;

    // Since we are dropping packets, things are not getting acked.  Set up our
    // MRP state to look like what it would have looked like if the packet had
    // not gotten dropped.

    PretendWeGotReplyFromServer(*this, commandSender.mExchangeCtx.Get());

    GetLoopback().mSentMessageCount                 = 0;
    GetLoopback().mNumMessagesToDrop                = 0;
    GetLoopback().mNumMessagesToAllowBeforeDropping = 0;
    GetLoopback().mDroppedMessageCount              = 0;

    EXPECT_EQ(commandSender.OnMessageReceived(commandSender.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)),
              CHIP_IM_GLOBAL_STATUS(Busy));
    EXPECT_EQ(mockCommandSenderDelegate.mError, CHIP_IM_GLOBAL_STATUS(Busy));
    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1);
    EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u);

    DrainAndServiceIO();

    // Client sent status report with invalid action, server's exchange has been closed, so all it sent is an MRP Ack
    EXPECT_EQ(GetLoopback().mSentMessageCount, 2u);
    CheckForInvalidAction(messageLog);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    ExpireSessionAliceToBob();
    ExpireSessionBobToAlice();
    EXPECT_SUCCESS(CreateSessionAliceToBob());
    EXPECT_SUCCESS(CreateSessionBobToAlice());
}

// Command Sender sends invoke request, command handler drops invoke response, then test injects unknown message to client,
// client sends out status response with invalid action.
TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage2)
{
    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    asyncCommand = false;

    GetLoopback().mSentMessageCount                 = 0;
    GetLoopback().mNumMessagesToDrop                = 1;
    GetLoopback().mNumMessagesToAllowBeforeDropping = 1;
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);
    DrainAndServiceIO();

    EXPECT_EQ(GetLoopback().mSentMessageCount, 2u);
    EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u);

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);

    System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes);
    ASSERT_FALSE(msgBuf.IsNull());
    System::PacketBufferTLVWriter writer;
    writer.Init(std::move(msgBuf));
    ReportDataMessage::Builder response;
    EXPECT_SUCCESS(response.Init(&writer));
    EXPECT_EQ(writer.Finalize(&msgBuf), CHIP_NO_ERROR);

    PayloadHeader payloadHeader;
    payloadHeader.SetExchangeID(0);
    payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::ReportData);
    chip::Testing::MessageCapturer messageLog(*this);
    messageLog.mCaptureStandaloneAcks = false;

    // Since we are dropping packets, things are not getting acked.  Set up our
    // MRP state to look like what it would have looked like if the packet had
    // not gotten dropped.

    PretendWeGotReplyFromServer(*this, commandSender.mExchangeCtx.Get());

    GetLoopback().mSentMessageCount                 = 0;
    GetLoopback().mNumMessagesToDrop                = 0;
    GetLoopback().mNumMessagesToAllowBeforeDropping = 0;
    GetLoopback().mDroppedMessageCount              = 0;

    EXPECT_EQ(commandSender.OnMessageReceived(commandSender.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)),
              CHIP_ERROR_INVALID_MESSAGE_TYPE);
    EXPECT_EQ(mockCommandSenderDelegate.mError, CHIP_ERROR_INVALID_MESSAGE_TYPE);
    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1);

    DrainAndServiceIO();

    // Client sent status report with invalid action, server's exchange has been closed, so all it sent is an MRP Ack
    EXPECT_EQ(GetLoopback().mSentMessageCount, 2u);
    CheckForInvalidAction(messageLog);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    ExpireSessionAliceToBob();
    ExpireSessionBobToAlice();
    EXPECT_SUCCESS(CreateSessionAliceToBob());
    EXPECT_SUCCESS(CreateSessionBobToAlice());
}

// Command Sender sends invoke request, command handler drops invoke response, then test injects malformed invoke response
// message to client, client sends out status response with invalid action.
TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage3)
{
    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    asyncCommand = false;

    GetLoopback().mSentMessageCount                 = 0;
    GetLoopback().mNumMessagesToDrop                = 1;
    GetLoopback().mNumMessagesToAllowBeforeDropping = 1;
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);
    DrainAndServiceIO();

    EXPECT_EQ(GetLoopback().mSentMessageCount, 2u);
    EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u);

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);

    System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes);
    ASSERT_FALSE(msgBuf.IsNull());
    System::PacketBufferTLVWriter writer;
    writer.Init(std::move(msgBuf));
    InvokeResponseMessage::Builder response;
    EXPECT_SUCCESS(response.Init(&writer));
    EXPECT_EQ(writer.Finalize(&msgBuf), CHIP_NO_ERROR);

    PayloadHeader payloadHeader;
    payloadHeader.SetExchangeID(0);
    payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::InvokeCommandResponse);
    chip::Testing::MessageCapturer messageLog(*this);
    messageLog.mCaptureStandaloneAcks = false;

    // Since we are dropping packets, things are not getting acked.  Set up our
    // MRP state to look like what it would have looked like if the packet had
    // not gotten dropped.
    PretendWeGotReplyFromServer(*this, commandSender.mExchangeCtx.Get());

    GetLoopback().mSentMessageCount                 = 0;
    GetLoopback().mNumMessagesToDrop                = 0;
    GetLoopback().mNumMessagesToAllowBeforeDropping = 0;
    GetLoopback().mDroppedMessageCount              = 0;

    EXPECT_EQ(commandSender.OnMessageReceived(commandSender.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)),
              CHIP_ERROR_END_OF_TLV);
    EXPECT_EQ(mockCommandSenderDelegate.mError, CHIP_ERROR_END_OF_TLV);
    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1);

    DrainAndServiceIO();

    // Client sent status report with invalid action, server's exchange has been closed, so all it sent is an MRP Ack
    EXPECT_EQ(GetLoopback().mSentMessageCount, 2u);
    CheckForInvalidAction(messageLog);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    ExpireSessionAliceToBob();
    ExpireSessionBobToAlice();
    EXPECT_SUCCESS(CreateSessionAliceToBob());
    EXPECT_SUCCESS(CreateSessionBobToAlice());
}

// Command Sender sends invoke request, command handler drops invoke response, then test injects malformed status response to
// client, client responds to the status response with invalid action.
TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandInvalidMessage4)
{
    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    asyncCommand = false;

    GetLoopback().mSentMessageCount                 = 0;
    GetLoopback().mNumMessagesToDrop                = 1;
    GetLoopback().mNumMessagesToAllowBeforeDropping = 1;
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);
    DrainAndServiceIO();

    EXPECT_EQ(GetLoopback().mSentMessageCount, 2u);
    EXPECT_EQ(GetLoopback().mDroppedMessageCount, 1u);

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);

    System::PacketBufferHandle msgBuf = System::PacketBufferHandle::New(kMaxSecureSduLengthBytes);
    ASSERT_FALSE(msgBuf.IsNull());
    System::PacketBufferTLVWriter writer;
    writer.Init(std::move(msgBuf));
    StatusResponseMessage::Builder response;
    EXPECT_SUCCESS(response.Init(&writer));
    EXPECT_EQ(writer.Finalize(&msgBuf), CHIP_NO_ERROR);

    PayloadHeader payloadHeader;
    payloadHeader.SetExchangeID(0);
    payloadHeader.SetMessageType(chip::Protocols::InteractionModel::MsgType::StatusResponse);
    chip::Testing::MessageCapturer messageLog(*this);
    messageLog.mCaptureStandaloneAcks = false;

    // Since we are dropping packets, things are not getting acked.  Set up our
    // MRP state to look like what it would have looked like if the packet had
    // not gotten dropped.
    PretendWeGotReplyFromServer(*this, commandSender.mExchangeCtx.Get());

    GetLoopback().mSentMessageCount                 = 0;
    GetLoopback().mNumMessagesToDrop                = 0;
    GetLoopback().mNumMessagesToAllowBeforeDropping = 0;
    GetLoopback().mDroppedMessageCount              = 0;

    EXPECT_EQ(commandSender.OnMessageReceived(commandSender.mExchangeCtx.Get(), payloadHeader, std::move(msgBuf)),
              CHIP_ERROR_END_OF_TLV);
    EXPECT_EQ(mockCommandSenderDelegate.mError, CHIP_ERROR_END_OF_TLV);
    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1);

    DrainAndServiceIO();

    // Client sent status report with invalid action, server's exchange has been closed, so all it sent is an MRP Ack
    EXPECT_EQ(GetLoopback().mSentMessageCount, 2u);
    CheckForInvalidAction(messageLog);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    ExpireSessionAliceToBob();
    ExpireSessionBobToAlice();
    EXPECT_SUCCESS(CreateSessionAliceToBob());
    EXPECT_SUCCESS(CreateSessionBobToAlice());
}

TEST_F(TestCommandInteraction, TestCommandSender_WithWrongState)
{

    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_ERROR_INCORRECT_STATE);
}

TEST_F(TestCommandInteraction, TestCommandHandler_WithWrongState)
{
    ConcreteCommandPath requestCommandPath  = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData };
    ConcreteCommandPath responseCommandPath = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData };

    CommandHandlerWithUnrespondedCommand commandHandler(&mockCommandHandlerDelegate, requestCommandPath,
                                                        /* aRef = */ NullOptional);

    {
        // This simulates how cluster would call CommandHandler APIs synchronously. There would
        // be handle already acquired on the callers behalf.
        CommandHandler::Handle handle(&commandHandler);

        const CommandHandlerImpl::InvokeResponseParameters prepareParams(requestCommandPath);
        EXPECT_EQ(commandHandler.PrepareInvokeResponseCommand(responseCommandPath, prepareParams), CHIP_NO_ERROR);
    }
    EXPECT_TRUE(commandHandler.mMockCommandResponder.mChunks.IsNull());
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_WithSendCommand)
{

    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);

    AddInvokeRequestData(&commandSender);
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    GenerateInvokeResponse(buf, kTestCommandIdWithData);
    bool moreChunkedMessages = false;
    EXPECT_EQ(commandSender.ProcessInvokeResponse(std::move(buf), moreChunkedMessages), CHIP_NO_ERROR);
    EXPECT_FALSE(moreChunkedMessages);
}

TEST_F(TestCommandInteraction, TestCommandHandler_WithSendEmptyCommand)
{
    ConcreteCommandPath requestCommandPath  = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData };
    ConcreteCommandPath responseCommandPath = { kTestEndpointId, kTestClusterId, kTestCommandIdNoData };

    CommandHandlerWithUnrespondedCommand commandHandler(&mockCommandHandlerDelegate, requestCommandPath,
                                                        /* aRef = */ NullOptional);

    {
        // This simulates how cluster would call CommandHandler APIs synchronously. There would
        // be handle already acquired on the callers behalf.
        CommandHandler::Handle handle(&commandHandler);

        const CommandHandlerImpl::InvokeResponseParameters prepareParams(requestCommandPath);
        EXPECT_EQ(commandHandler.PrepareInvokeResponseCommand(responseCommandPath, prepareParams), CHIP_NO_ERROR);
        EXPECT_EQ(commandHandler.FinishCommand(), CHIP_NO_ERROR);
    }
    EXPECT_FALSE(commandHandler.mMockCommandResponder.mChunks.IsNull());
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_WithProcessReceivedMsg)
{

    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);

    GenerateInvokeResponse(buf, kTestCommandIdWithData);
    bool moreChunkedMessages = false;

    EXPECT_EQ(commandSender.ProcessInvokeResponse(std::move(buf), moreChunkedMessages), CHIP_NO_ERROR);
    EXPECT_FALSE(moreChunkedMessages);
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_ExtendableApiWithProcessReceivedMsg)
{

    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    uint16_t mockCommandRef = 1;
    EXPECT_SUCCESS(pendingResponseTracker.Add(mockCommandRef));
    commandSender.mFinishedCommandCount = 1;

    System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);

    GenerateInvokeResponse(buf, kTestCommandIdWithData);
    bool moreChunkedMessages = false;
    EXPECT_EQ(commandSender.ProcessInvokeResponse(std::move(buf), moreChunkedMessages), CHIP_NO_ERROR);
    EXPECT_FALSE(moreChunkedMessages);

    commandSender.FlushNoCommandResponse();

    EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onNoResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onErrorCalledTimes, 0);
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_ExtendableApiWithProcessReceivedMsgContainingInvalidCommandRef)
{

    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    uint16_t mockCommandRef = 1;
    EXPECT_SUCCESS(pendingResponseTracker.Add(mockCommandRef));

    commandSender.mFinishedCommandCount = 1;

    System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);

    uint16_t invalidResponseCommandRef = 2;
    GenerateInvokeResponse(buf, kTestCommandIdWithData, kTestClusterId, kTestEndpointId,
                           std::make_optional(invalidResponseCommandRef));
    bool moreChunkedMessages = false;
    EXPECT_EQ(commandSender.ProcessInvokeResponse(std::move(buf), moreChunkedMessages), CHIP_ERROR_KEY_NOT_FOUND);
    EXPECT_FALSE(moreChunkedMessages);

    commandSender.FlushNoCommandResponse();

    EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onNoResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onErrorCalledTimes, 0);
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandSender_ValidateSecondLargeAddRequestDataRollbacked)
{
    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    app::CommandSender::AddRequestDataParameters addRequestDataParams;

    CommandSender::ConfigParameters config;
    config.SetRemoteMaxPathsPerInvoke(2);
    EXPECT_EQ(commandSender.SetCommandSenderConfig(config), CHIP_NO_ERROR);

    // The specific values chosen here are arbitrary.
    uint16_t firstCommandRef  = 1;
    uint16_t secondCommandRef = 2;
    auto commandPathParams    = MakeTestCommandPath();
    SimpleTLVPayload simplePayloadWriter;
    addRequestDataParams.SetCommandRef(firstCommandRef);

    EXPECT_EQ(commandSender.AddRequestData(commandPathParams, simplePayloadWriter, addRequestDataParams), CHIP_NO_ERROR);

    uint32_t remainingSize = commandSender.mInvokeRequestBuilder.GetWriter()->GetRemainingFreeLength();
    // Because request is made of both request data and request path (commandPathParams), using
    // `remainingSize` is large enough fail.
    ForcedSizeBuffer requestData(remainingSize);

    addRequestDataParams.SetCommandRef(secondCommandRef);
    EXPECT_EQ(commandSender.AddRequestData(commandPathParams, requestData, addRequestDataParams), CHIP_ERROR_NO_MEMORY);

    // Confirm that we can still send out a request with the first command.
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);
    EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onErrorCalledTimes, 0);
}

TEST_F(TestCommandInteraction, TestCommandSender_FillUpRequest)
{
    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    app::CommandSender::AddRequestDataParameters addRequestDataParams;

    CommandSender::ConfigParameters config;
    EXPECT_EQ(commandSender.SetCommandSenderConfig(config), CHIP_NO_ERROR);

    auto firstCommandPathParams = MakeTestCommandPath(kTestCommandIdIgnoreCommandFields);
    FillTLVBuffer payloadWriter;
    EXPECT_EQ(commandSender.AddRequestData(firstCommandPathParams, payloadWriter, addRequestDataParams), CHIP_NO_ERROR);

    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);
    EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u);

    sendResponse           = true;
    commandDispatchedCount = 0;
    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onErrorCalledTimes, 0);
}

TEST_F(TestCommandInteraction, TestCommandHandler_CommandHandlerFillsUpResponse)
{
    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    app::CommandSender::AddRequestDataParameters addRequestDataParams;

    CommandSender::ConfigParameters config;
    EXPECT_EQ(commandSender.SetCommandSenderConfig(config), CHIP_NO_ERROR);

    auto firstCommandPathParams = MakeTestCommandPath(kTestCommandIdFillResponseMessage);
    SimpleTLVPayload simplePayloadWriter;
    EXPECT_EQ(commandSender.AddRequestData(firstCommandPathParams, simplePayloadWriter, addRequestDataParams), CHIP_NO_ERROR);

    // Confirm that we can still send out a request with the first command.
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);
    EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u);

    sendResponse           = true;
    commandDispatchedCount = 0;
    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onErrorCalledTimes, 0);
}

TEST_F(TestCommandInteraction, TestCommandHandlerEncodeSimpleCommandData)
{
    // Send response which has simple command data and command path
    ValidateCommandHandlerEncodeInvokeResponseMessage(false /*aNeedStatusCode=false*/);
}

TEST_F(TestCommandInteraction, TestCommandHandlerCommandDataEncoding)
{
    auto path = MakeTestCommandPath();
    ConcreteCommandPath requestCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId);
    CommandHandlerWithUnrespondedCommand commandHandler(nullptr, requestCommandPath, /* aRef = */ NullOptional);

    {
        // This simulates how cluster would call CommandHandler APIs synchronously. There would
        // be handle already acquired on the callers behalf.
        CommandHandler::Handle handle(&commandHandler);

        commandHandler.AddResponse(requestCommandPath, Fields());
    }
    EXPECT_FALSE(commandHandler.mMockCommandResponder.mChunks.IsNull());
}

TEST_F(TestCommandInteraction, TestCommandHandlerCommandEncodeFailure)
{
    auto path               = MakeTestCommandPath();
    auto requestCommandPath = ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId);
    CommandHandlerWithUnrespondedCommand commandHandler(nullptr, requestCommandPath, NullOptional);

    {
        // This simulates how cluster would call CommandHandler APIs synchronously. There would
        // be handle already acquired on the callers behalf.
        CommandHandler::Handle handle(&commandHandler);

        commandHandler.AddResponse(requestCommandPath, BadFields());
    }
    EXPECT_FALSE(commandHandler.mMockCommandResponder.mChunks.IsNull());
}

// Command Sender sends malformed invoke request, handler fails to process it and sends status report with invalid action
TEST_F(TestCommandInteraction, TestCommandHandlerInvalidMessageSync)
{

    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    chip::isCommandDispatched = false;
    AddInvalidInvokeRequestData(&commandSender);
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_FALSE(chip::isCommandDispatched);
    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.mError, CHIP_IM_GLOBAL_STATUS(InvalidAction));
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandHandlerCommandEncodeExternalFailure)
{
    auto path               = MakeTestCommandPath();
    auto requestCommandPath = ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId);
    CommandHandlerWithUnrespondedCommand commandHandler(nullptr, requestCommandPath, NullOptional);

    {
        // This simulates how cluster would call CommandHandler APIs synchronously. There would
        // be handle already acquired on the callers behalf.
        CommandHandler::Handle handle(&commandHandler);

        EXPECT_NE(commandHandler.AddResponseData(requestCommandPath, BadFields()), CHIP_NO_ERROR);
        commandHandler.AddStatus(requestCommandPath, Protocols::InteractionModel::Status::Failure);
    }
    EXPECT_FALSE(commandHandler.mMockCommandResponder.mChunks.IsNull());
}

TEST_F(TestCommandInteraction, TestCommandHandlerEncodeSimpleStatusCode)
{
    // Send response which has simple status code and command path
    ValidateCommandHandlerEncodeInvokeResponseMessage(true /*aNeedStatusCode=true*/);
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_WithoutResponderCallingAddStatus)
{
    chip::app::ConcreteCommandPath requestCommandPath(kTestEndpointId, kTestClusterId, kTestCommandIdWithData);
    CommandHandlerImpl commandHandler(&mockCommandHandlerDelegate);

    commandHandler.AddStatus(requestCommandPath, Protocols::InteractionModel::Status::Failure);

    // Since calling AddStatus is supposed to be a no-operation when there is no responder, it is
    // hard to validate. Best way is to check that we are still in an Idle state afterwards
    EXPECT_TRUE(commandHandler.TestOnlyIsInIdleState());
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_WithoutResponderCallingAddResponse)
{
    chip::app::ConcreteCommandPath requestCommandPath(kTestEndpointId, kTestClusterId, kTestCommandIdWithData);
    CommandHandlerImpl commandHandler(&mockCommandHandlerDelegate);

    uint32_t sizeToFill = 50; // This is an arbitrary number, we need to select a non-zero value.
    ForcedSizeBuffer responseData(sizeToFill);
    EXPECT_EQ(commandHandler.AddResponseData(requestCommandPath, responseData.GetCommandId(), responseData), CHIP_NO_ERROR);

    // Since calling AddResponseData is supposed to be a no-operation when there is no responder, it is
    // hard to validate. Best way is to check that we are still in an Idle state afterwards
    EXPECT_TRUE(commandHandler.TestOnlyIsInIdleState());
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_WithoutResponderCallingDirectPrepareFinishCommandApis)
{
    chip::app::ConcreteCommandPath requestCommandPath(kTestEndpointId, kTestClusterId, kTestCommandIdWithData);
    CommandHandlerImpl commandHandler(&mockCommandHandlerDelegate);

    // We intentionally prevent successful calls to PrepareInvokeResponseCommand and FinishCommand when no
    // responder is present. This aligns with the design decision to promote AddStatus and AddResponseData
    // usage in such scenarios. See GitHub issue #32486 for discussions on phasing out external use of
    // these primitives.
    const CommandHandlerImpl::InvokeResponseParameters prepareParams(requestCommandPath);
    ConcreteCommandPath responseCommandPath = { kTestEndpointId, kTestClusterId, kTestCommandIdCommandSpecificResponse };
    EXPECT_EQ(commandHandler.PrepareInvokeResponseCommand(responseCommandPath, prepareParams), CHIP_ERROR_INCORRECT_STATE);

    EXPECT_EQ(commandHandler.GetCommandDataIBTLVWriter(), nullptr);

    EXPECT_EQ(commandHandler.FinishCommand(), CHIP_ERROR_INCORRECT_STATE);

    EXPECT_TRUE(commandHandler.TestOnlyIsInIdleState());
}

TEST_F(TestCommandInteraction, TestCommandHandler_WithOnInvokeReceivedNotExistCommand)
{
    System::PacketBufferHandle commandDatabuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);
    // Use some invalid endpoint / cluster / command.
    GenerateInvokeRequest(commandDatabuf, /* aIsTimedRequest = */ false, 0xEF /* command */, 0xADBE /* cluster */,
                          0xDE /* endpoint */);
    CommandHandlerImpl commandHandler(&mockCommandHandlerDelegate);
    chip::isCommandDispatched = false;

    mockCommandHandlerDelegate.ResetCounter();
    MockCommandResponder mockCommandResponder;
    Protocols::InteractionModel::Status status =
        commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false);

    EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction);
    EXPECT_TRUE(mockCommandResponder.mChunks.IsNull());
    // TODO we can further validate the response is what we expected.
    EXPECT_FALSE(chip::isCommandDispatched);
}

TEST_F(TestCommandInteraction, TestCommandHandler_WithOnInvokeReceivedEmptyDataMsg)
{
    bool allBooleans[] = { true, false };
    for (auto messageIsTimed : allBooleans)
    {
        for (auto transactionIsTimed : allBooleans)
        {
            mockCommandHandlerDelegate.ResetCounter();
            CommandHandlerImpl commandHandler(&mockCommandHandlerDelegate);
            System::PacketBufferHandle commandDatabuf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize);

            chip::isCommandDispatched = false;
            GenerateInvokeRequest(commandDatabuf, messageIsTimed, kTestCommandIdNoData);
            MockCommandResponder mockCommandResponder;
            Protocols::InteractionModel::Status status =
                commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), transactionIsTimed);

            if (messageIsTimed != transactionIsTimed)
            {
                EXPECT_EQ(status, Protocols::InteractionModel::Status::TimedRequestMismatch);
                EXPECT_TRUE(mockCommandResponder.mChunks.IsNull());
            }
            else
            {
                EXPECT_EQ(status, Protocols::InteractionModel::Status::Success);
                EXPECT_FALSE(mockCommandResponder.mChunks.IsNull());
            }
            EXPECT_TRUE(chip::isCommandDispatched == (messageIsTimed == transactionIsTimed));
        }
    }
}

TEST_F(TestCommandInteraction, TestCommandSenderLegacyCallbackUnsupportedCommand)
{

    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender, kTestNonExistCommandId);
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

// Because UnsupportedCommand is a path specific error we will expect it to come via on response when using Extended Path.
TEST_F(TestCommandInteraction, TestCommandSender_ExtendableCallbackUnsupportedCommand)
{

    mockCommandSenderExtendedDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderExtendedDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender, kTestNonExistCommandId);
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onErrorCalledTimes, 0);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSenderLegacyCallbackBuildingBatchCommandFails)
{
    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());
    app::CommandSender::PrepareCommandParameters prepareCommandParams;
    app::CommandSender::FinishCommandParameters finishCommandParams;
    prepareCommandParams.SetStartDataStruct(true).SetCommandRef(0);
    finishCommandParams.SetEndDataStruct(true).SetCommandRef(0);

    CommandSender::ConfigParameters config;
    config.SetRemoteMaxPathsPerInvoke(2);
    EXPECT_EQ(commandSender.SetCommandSenderConfig(config), CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
    // Even though we got an error saying invalid argument we are going to attempt
    // to add two commands.

    auto commandPathParams = MakeTestCommandPath();
    EXPECT_EQ(commandSender.PrepareCommand(commandPathParams, prepareCommandParams), CHIP_NO_ERROR);
    chip::TLV::TLVWriter * writer = commandSender.GetCommandDataIBTLVWriter();
    EXPECT_EQ(writer->PutBoolean(chip::TLV::ContextTag(1), true), CHIP_NO_ERROR);
    EXPECT_EQ(commandSender.FinishCommand(finishCommandParams), CHIP_NO_ERROR);
    // Preparing second command.
    prepareCommandParams.SetCommandRef(1);
    EXPECT_EQ(commandSender.PrepareCommand(commandPathParams, prepareCommandParams), CHIP_ERROR_INCORRECT_STATE);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSender_ExtendableCallbackBuildingBatchDuplicateCommandRefFails)
{
    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);
    app::CommandSender::PrepareCommandParameters prepareCommandParams;
    app::CommandSender::FinishCommandParameters finishCommandParams;

    CommandSender::ConfigParameters config;
    config.SetRemoteMaxPathsPerInvoke(2);
    EXPECT_EQ(commandSender.SetCommandSenderConfig(config), CHIP_NO_ERROR);

    prepareCommandParams.SetStartDataStruct(true).SetCommandRef(0);
    finishCommandParams.SetEndDataStruct(true).SetCommandRef(0);
    auto commandPathParams = MakeTestCommandPath();
    EXPECT_EQ(commandSender.PrepareCommand(commandPathParams, prepareCommandParams), CHIP_NO_ERROR);
    chip::TLV::TLVWriter * writer = commandSender.GetCommandDataIBTLVWriter();
    EXPECT_EQ(writer->PutBoolean(chip::TLV::ContextTag(1), true), CHIP_NO_ERROR);
    EXPECT_EQ(commandSender.FinishCommand(finishCommandParams), CHIP_NO_ERROR);
    // Preparing second command.
    prepareCommandParams.SetCommandRef(0);
    EXPECT_EQ(commandSender.PrepareCommand(commandPathParams, prepareCommandParams), CHIP_ERROR_INVALID_ARGUMENT);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSender_ExtendableCallbackBuildingBatchCommandSuccess)
{
    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);
    app::CommandSender::PrepareCommandParameters prepareCommandParams;
    app::CommandSender::FinishCommandParameters finishCommandParams;

    CommandSender::ConfigParameters config;
    config.SetRemoteMaxPathsPerInvoke(2);
    EXPECT_EQ(commandSender.SetCommandSenderConfig(config), CHIP_NO_ERROR);

    // The specific values chosen here are arbitrary. This test primarily verifies that we can
    // use a larger command reference value followed by a smaller one for subsequent command.
    uint16_t firstCommandRef  = 40;
    uint16_t secondCommandRef = 2;
    prepareCommandParams.SetStartDataStruct(true).SetCommandRef(firstCommandRef);
    finishCommandParams.SetEndDataStruct(true).SetCommandRef(firstCommandRef);
    auto commandPathParams = MakeTestCommandPath();
    EXPECT_EQ(commandSender.PrepareCommand(commandPathParams, prepareCommandParams), CHIP_NO_ERROR);
    chip::TLV::TLVWriter * writer = commandSender.GetCommandDataIBTLVWriter();
    EXPECT_EQ(writer->PutBoolean(chip::TLV::ContextTag(1), true), CHIP_NO_ERROR);
    EXPECT_EQ(commandSender.FinishCommand(finishCommandParams), CHIP_NO_ERROR);
    // Preparing second command.
    prepareCommandParams.SetCommandRef(secondCommandRef);
    finishCommandParams.SetCommandRef(secondCommandRef);
    EXPECT_EQ(commandSender.PrepareCommand(commandPathParams, prepareCommandParams), CHIP_NO_ERROR);
    writer = commandSender.GetCommandDataIBTLVWriter();
    EXPECT_EQ(writer->PutBoolean(chip::TLV::ContextTag(1), true), CHIP_NO_ERROR);
    EXPECT_EQ(commandSender.FinishCommand(finishCommandParams), CHIP_NO_ERROR);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSenderCommandSuccessResponseFlow)
{

    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);
    EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);

    EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 1u);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSenderGroupCommandNoResponseFlow)
{
    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    SessionHandle groupSession = GetSessionBobToFriends();
    EXPECT_TRUE(groupSession->IsGroupSession());
    EXPECT_EQ(commandSender.SendGroupCommandRequest(groupSession), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    // No response is expected for a group command, so OnResponse and OnError should not be called.
    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);
    // There should be no invoke response messages.
    EXPECT_EQ(commandSender.GetInvokeResponseMessageCount(), 0u);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSenderCommandAsyncSuccessResponseFlow)
{

    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    asyncCommand = true;

    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 1u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 2u);

    // Decrease CommandHandler refcount and send response
    asyncCommandHandle = nullptr;

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, CommandSenderDeletedWhenResponseIsPending)
{

    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender * commandSender = Platform::New<app::CommandSender>(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(commandSender);
    asyncCommand = true;

    EXPECT_EQ(commandSender->SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 1u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 2u);

    // This is NOT deleting CommandSender in one of the callbacks, so we are not violating
    // the API contract. CommandSender is deleted when no message is being processed which
    // is a time that deleting CommandSender is considered safe.
    Platform::Delete(commandSender);

    // Decrease CommandHandler refcount and send response
    asyncCommandHandle = nullptr;

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSenderCommandSpecificResponseFlow)
{

    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender, kTestCommandIdCommandSpecificResponse);
    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSenderCommandFailureResponseFlow)
{

    mockCommandSenderDelegate.ResetCounter();
    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender, kTestNonExistCommandId);

    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 1);
    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandSenderAbruptDestruction)
{

    //
    // Don't send back a response, just keep the CommandHandler
    // hanging to give us enough time to do what we want with the CommandSender object.
    //
    sendResponse = false;

    mockCommandSenderDelegate.ResetCounter();

    {
        app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

        AddInvokeRequestData(&commandSender, kTestCommandIdCommandSpecificResponse);

        EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

        DrainAndServiceIO();

        //
        // No callbacks should be invoked yet - let's validate that.
        //
        EXPECT_EQ(mockCommandSenderDelegate.onResponseCalledTimes, 0);
        EXPECT_EQ(mockCommandSenderDelegate.onFinalCalledTimes, 0);
        EXPECT_EQ(mockCommandSenderDelegate.onErrorCalledTimes, 0);

        EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 1u);
    }

    //
    // Upon the sender being destructed by the application, our exchange should get cleaned up too.
    //
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
}

TEST_F(TestCommandInteraction, TestCommandHandler_RejectMultipleIdenticalCommands)
{

    isCommandDispatched = false;
    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    app::CommandSender::ConfigParameters configParameters;
    configParameters.SetRemoteMaxPathsPerInvoke(2);
    EXPECT_EQ(CHIP_NO_ERROR, commandSender.SetCommandSenderConfig(configParameters));

    // Command ID is not important here, since the command handler should reject the commands without handling it.
    auto commandPathParams = MakeTestCommandPath(kTestCommandIdCommandSpecificResponse);

    for (uint16_t i = 0; i < 2; i++)
    {
        app::CommandSender::PrepareCommandParameters prepareCommandParams;
        prepareCommandParams.SetStartDataStruct(true);
        prepareCommandParams.SetCommandRef(i);
        EXPECT_EQ(CHIP_NO_ERROR, commandSender.PrepareCommand(commandPathParams, prepareCommandParams));
        EXPECT_EQ(CHIP_NO_ERROR, commandSender.GetCommandDataIBTLVWriter()->PutBoolean(chip::TLV::ContextTag(1), true));

        app::CommandSender::FinishCommandParameters finishCommandParams;
        finishCommandParams.SetEndDataStruct(true);
        finishCommandParams.SetCommandRef(i);
        EXPECT_EQ(CHIP_NO_ERROR, commandSender.FinishCommand(finishCommandParams));
    }

    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    EXPECT_EQ(mockCommandSenderExtendedDelegate.onResponseCalledTimes, 0);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onFinalCalledTimes, 1);
    EXPECT_EQ(mockCommandSenderExtendedDelegate.onErrorCalledTimes, 1);
    EXPECT_FALSE(chip::isCommandDispatched);

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_RejectsMultipleCommandsWithIdenticalCommandRef)
{

    isCommandDispatched = false;
    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    app::CommandSender::ConfigParameters configParameters;
    configParameters.SetRemoteMaxPathsPerInvoke(2);
    EXPECT_EQ(CHIP_NO_ERROR, commandSender.SetCommandSenderConfig(configParameters));

    uint16_t numberOfCommandsToSend = 2;
    {
        CommandPathParams requestCommandPaths[] = {
            MakeTestCommandPath(kTestCommandIdWithData),
            MakeTestCommandPath(kTestCommandIdCommandSpecificResponse),
        };

        uint16_t hardcodedCommandRef = 0;

        for (uint16_t i = 0; i < numberOfCommandsToSend; i++)
        {
            app::CommandSender::PrepareCommandParameters prepareCommandParams;
            prepareCommandParams.SetStartDataStruct(true);
            prepareCommandParams.SetCommandRef(i);
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.PrepareCommand(requestCommandPaths[i], prepareCommandParams));
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.GetCommandDataIBTLVWriter()->PutBoolean(chip::TLV::ContextTag(1), true));
            // TODO fix this comment
            // We are taking advantage of the fact that the commandRef was set into finishCommandParams during PrepareCommand
            // But setting it to a different value here, we are overriding what it was supposed to be.
            app::CommandSender::FinishCommandParameters finishCommandParams;
            finishCommandParams.SetEndDataStruct(true);
            finishCommandParams.SetCommandRef(hardcodedCommandRef);
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.TestOnlyFinishCommand(finishCommandParams));
        }
    }

    BasicCommandPathRegistry<4> basicCommandPathRegistry;
    MockCommandResponder mockCommandResponder;
    CommandHandlerImpl::TestOnlyOverrides testOnlyOverrides{ &basicCommandPathRegistry, &mockCommandResponder };
    CommandHandlerImpl commandHandler(testOnlyOverrides, &mockCommandHandlerDelegate);

    // Hackery to steal the InvokeRequest buffer from commandSender.
    System::PacketBufferHandle commandDatabuf;
    EXPECT_EQ(commandSender.Finalize(commandDatabuf), CHIP_NO_ERROR);

    mockCommandHandlerDelegate.ResetCounter();
    commandDispatchedCount = 0;

    Protocols::InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false);
    EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction);

    EXPECT_EQ(commandDispatchedCount, 0u);
}

#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_RejectMultipleCommandsWhenHandlerOnlySupportsOne)
{

    isCommandDispatched = false;

    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    app::CommandSender::ConfigParameters configParameters;
    configParameters.SetRemoteMaxPathsPerInvoke(2);
    EXPECT_EQ(CHIP_NO_ERROR, commandSender.SetCommandSenderConfig(configParameters));

    uint16_t numberOfCommandsToSend = 2;
    {
        CommandPathParams requestCommandPaths[] = {
            MakeTestCommandPath(kTestCommandIdWithData),
            MakeTestCommandPath(kTestCommandIdCommandSpecificResponse),
        };

        for (uint16_t i = 0; i < numberOfCommandsToSend; i++)
        {
            app::CommandSender::PrepareCommandParameters prepareCommandParams;
            prepareCommandParams.SetStartDataStruct(true);
            prepareCommandParams.SetCommandRef(i);
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.PrepareCommand(requestCommandPaths[i], prepareCommandParams));
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.GetCommandDataIBTLVWriter()->PutBoolean(chip::TLV::ContextTag(1), true));
            app::CommandSender::FinishCommandParameters finishCommandParams;
            finishCommandParams.SetEndDataStruct(true);
            finishCommandParams.SetCommandRef(i);
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.FinishCommand(finishCommandParams));
        }
    }

    // Hackery to steal the InvokeRequest buffer from commandSender.
    System::PacketBufferHandle commandDatabuf;
    EXPECT_EQ(commandSender.Finalize(commandDatabuf), CHIP_NO_ERROR);

    mockCommandHandlerDelegate.ResetCounter();
    sendResponse           = true;
    commandDispatchedCount = 0;

    CommandHandlerImpl commandHandler(&mockCommandHandlerDelegate);
    MockCommandResponder mockCommandResponder;
    Protocols::InteractionModel::Status status =
        commandHandler.OnInvokeCommandRequest(mockCommandResponder, std::move(commandDatabuf), false);
    EXPECT_EQ(status, Protocols::InteractionModel::Status::InvalidAction);
    EXPECT_TRUE(mockCommandResponder.mChunks.IsNull());

    EXPECT_EQ(commandDispatchedCount, 0u);
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_AcceptMultipleCommands)
{

    isCommandDispatched = false;

    mockCommandSenderExtendedDelegate.ResetCounter();
    PendingResponseTrackerImpl pendingResponseTracker;
    app::CommandSender commandSender(kCommandSenderTestOnlyMarker, &mockCommandSenderExtendedDelegate, &GetExchangeManager(),
                                     &pendingResponseTracker);

    app::CommandSender::ConfigParameters configParameters;
    configParameters.SetRemoteMaxPathsPerInvoke(2);
    EXPECT_EQ(CHIP_NO_ERROR, commandSender.SetCommandSenderConfig(configParameters));

    uint16_t numberOfCommandsToSend = 2;
    {
        CommandPathParams requestCommandPaths[] = {
            MakeTestCommandPath(kTestCommandIdWithData),
            MakeTestCommandPath(kTestCommandIdCommandSpecificResponse),
        };

        for (uint16_t i = 0; i < numberOfCommandsToSend; i++)
        {
            app::CommandSender::PrepareCommandParameters prepareCommandParams;
            prepareCommandParams.SetStartDataStruct(true);
            prepareCommandParams.SetCommandRef(i);
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.PrepareCommand(requestCommandPaths[i], prepareCommandParams));
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.GetCommandDataIBTLVWriter()->PutBoolean(chip::TLV::ContextTag(1), true));
            app::CommandSender::FinishCommandParameters finishCommandParams;
            finishCommandParams.SetEndDataStruct(true);
            finishCommandParams.SetCommandRef(i);
            EXPECT_EQ(CHIP_NO_ERROR, commandSender.FinishCommand(finishCommandParams));
        }
        commandSender.MoveToState(app::CommandSender::State::AddedCommand);
    }

    BasicCommandPathRegistry<4> basicCommandPathRegistry;
    MockCommandResponder mockCommandResponder;
    CommandHandlerImpl::TestOnlyOverrides testOnlyOverrides{ &basicCommandPathRegistry, &mockCommandResponder };
    CommandHandlerImpl commandHandler(testOnlyOverrides, &mockCommandHandlerDelegate);

    // Hackery to steal the InvokeRequest buffer from commandSender.
    System::PacketBufferHandle commandDatabuf;
    EXPECT_EQ(commandSender.Finalize(commandDatabuf), CHIP_NO_ERROR);

    sendResponse = true;
    mockCommandHandlerDelegate.ResetCounter();
    commandDispatchedCount = 0;

    Protocols::InteractionModel::Status status = commandHandler.ProcessInvokeRequest(std::move(commandDatabuf), false);
    EXPECT_EQ(status, Protocols::InteractionModel::Status::Success);

    EXPECT_EQ(commandDispatchedCount, 2u);
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_FillUpInvokeResponseMessageWhereSecondResponseIsStatusResponse)
{
    BasicCommandPathRegistry<4> basicCommandPathRegistry;
    MockCommandResponder mockCommandResponder;
    CommandHandlerImpl::TestOnlyOverrides testOnlyOverrides{ &basicCommandPathRegistry, &mockCommandResponder };
    CommandHandlerImpl commandHandler(testOnlyOverrides, &mockCommandHandlerDelegate);

    commandHandler.mReserveSpaceForMoreChunkMessages = true;
    ConcreteCommandPath requestCommandPath1          = { kTestEndpointId, kTestClusterId, kTestCommandIdFillResponseMessage };
    ConcreteCommandPath requestCommandPath2          = { kTestEndpointId, kTestClusterId, kTestCommandIdCommandSpecificResponse };

    EXPECT_EQ(basicCommandPathRegistry.Add(requestCommandPath1, std::make_optional<uint16_t>(static_cast<uint16_t>(1))),
              CHIP_NO_ERROR);
    EXPECT_EQ(basicCommandPathRegistry.Add(requestCommandPath2, std::make_optional<uint16_t>(static_cast<uint16_t>(2))),
              CHIP_NO_ERROR);

    uint32_t sizeToLeave = 0;
    FillCurrentInvokeResponseBuffer(&commandHandler, requestCommandPath1, sizeToLeave);
    uint32_t remainingSize = commandHandler.mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();
    EXPECT_EQ(remainingSize, sizeToLeave);

    AddInvokeResponseData(&commandHandler, /* aNeedStatusCode = */ true, kTestCommandIdCommandSpecificResponse,
                          kTestCommandIdCommandSpecificResponse);

    remainingSize = commandHandler.mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();
    EXPECT_GT(remainingSize, sizeToLeave);
}
TEST_F_FROM_FIXTURE(TestCommandInteraction,
                    TestCommandHandler_FillUpInvokeResponseMessageWhereSecondResponseIsDataResponsePrimative)
{
    BasicCommandPathRegistry<4> basicCommandPathRegistry;
    MockCommandResponder mockCommandResponder;
    CommandHandlerImpl::TestOnlyOverrides testOnlyOverrides{ &basicCommandPathRegistry, &mockCommandResponder };
    CommandHandlerImpl commandHandler(testOnlyOverrides, &mockCommandHandlerDelegate);

    commandHandler.mReserveSpaceForMoreChunkMessages = true;
    ConcreteCommandPath requestCommandPath1          = { kTestEndpointId, kTestClusterId, kTestCommandIdFillResponseMessage };
    ConcreteCommandPath requestCommandPath2          = { kTestEndpointId, kTestClusterId, kTestCommandIdCommandSpecificResponse };

    EXPECT_EQ(basicCommandPathRegistry.Add(requestCommandPath1, std::make_optional<uint16_t>(static_cast<uint16_t>(1))),
              CHIP_NO_ERROR);
    EXPECT_EQ(basicCommandPathRegistry.Add(requestCommandPath2, std::make_optional<uint16_t>(static_cast<uint16_t>(2))),
              CHIP_NO_ERROR);

    uint32_t sizeToLeave = 0;
    FillCurrentInvokeResponseBuffer(&commandHandler, requestCommandPath1, sizeToLeave);
    uint32_t remainingSize = commandHandler.mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();
    EXPECT_EQ(remainingSize, sizeToLeave);

    AddInvokeResponseData(&commandHandler, /* aNeedStatusCode = */ false, kTestCommandIdCommandSpecificResponse,
                          kTestCommandIdCommandSpecificResponse);

    remainingSize = commandHandler.mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();
    EXPECT_GT(remainingSize, sizeToLeave);
}

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_FillUpInvokeResponseMessageWhereSecondResponseIsDataResponse)
{
    BasicCommandPathRegistry<4> basicCommandPathRegistry;
    MockCommandResponder mockCommandResponder;
    CommandHandlerImpl::TestOnlyOverrides testOnlyOverrides{ &basicCommandPathRegistry, &mockCommandResponder };
    CommandHandlerImpl commandHandler(testOnlyOverrides, &mockCommandHandlerDelegate);
    commandHandler.mReserveSpaceForMoreChunkMessages = true;
    ConcreteCommandPath requestCommandPath1          = { kTestEndpointId, kTestClusterId, kTestCommandIdFillResponseMessage };
    ConcreteCommandPath requestCommandPath2          = { kTestEndpointId, kTestClusterId, kTestCommandIdCommandSpecificResponse };

    EXPECT_EQ(basicCommandPathRegistry.Add(requestCommandPath1, std::make_optional<uint16_t>(static_cast<uint16_t>(1))),
              CHIP_NO_ERROR);
    EXPECT_EQ(basicCommandPathRegistry.Add(requestCommandPath2, std::make_optional<uint16_t>(static_cast<uint16_t>(2))),
              CHIP_NO_ERROR);

    uint32_t sizeToLeave = 0;
    FillCurrentInvokeResponseBuffer(&commandHandler, requestCommandPath1, sizeToLeave);
    uint32_t remainingSize = commandHandler.mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();
    EXPECT_EQ(remainingSize, sizeToLeave);

    uint32_t sizeToFill = 50;
    ForcedSizeBuffer responseData(sizeToFill);
    EXPECT_EQ(commandHandler.AddResponseData(requestCommandPath2, responseData.GetCommandId(), responseData), CHIP_NO_ERROR);

    remainingSize = commandHandler.mInvokeResponseBuilder.GetWriter()->GetRemainingFreeLength();
    EXPECT_GT(remainingSize, sizeToLeave);
}

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
//
// This test needs a special unit-test only API being exposed in ExchangeContext to be able to correctly simulate
// the release of a session on the exchange.
//
TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_ReleaseWithExchangeClosed)
{

    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    asyncCommandHandle = nullptr;
    asyncCommand       = true;

    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    // Verify that async command handle has been allocated
    ASSERT_NE(asyncCommandHandle.Get(), nullptr);

    // Mimic closure of the exchange that would happen on a session release and verify that releasing the handle there-after
    // is handled gracefully.
    asyncCommandHandle.TestOnlyReleaseSession();
    asyncCommandHandle = nullptr;
}
#endif

TEST_F_FROM_FIXTURE(TestCommandInteraction, TestCommandHandler_GetExchangeContextWhenAsync)
{

    app::CommandSender commandSender(&mockCommandSenderDelegate, &GetExchangeManager());

    AddInvokeRequestData(&commandSender);
    asyncCommandHandle = nullptr;
    asyncCommand       = true;

    EXPECT_EQ(commandSender.SendCommandRequest(GetSessionBobToAlice()), CHIP_NO_ERROR);

    DrainAndServiceIO();

    // Verify that async command handle has been allocated
    CommandHandler * handler = asyncCommandHandle.Get();
    ASSERT_NE(handler, nullptr);

    // when gone async: Ensure that GetExchangeContext returns nullptr while TryGetExchangeContextWhenAsync returns a valid pointer
    ASSERT_EQ(handler->GetExchangeContext(), nullptr);

    // Cast to CommandHandlerImpl to access TryGetExchangeContextWhenAsync, which is not accessible via CommandHandler
    auto * impl = static_cast<CommandHandlerImpl *>(handler);
    ASSERT_NE(impl->TryGetExchangeContextWhenAsync(), nullptr);

    asyncCommandHandle = nullptr;

    DrainAndServiceIO();

    EXPECT_EQ(GetNumActiveCommandResponderObjects(), 0u);
    EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u);
}

} // namespace app
} // namespace chip
