/*
 *
 *    Copyright (c) 2020-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 the ReliableMessageProtocol
 *      implementation.
 */
#include <queue>

#include <errno.h>

#include <pw_unit_test/framework.h>

#include <app/icd/server/ICDServerConfig.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/StringBuilderAdapters.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/tests/ExtraPwTestMacros.h>
#include <messaging/ReliableMessageContext.h>
#include <messaging/ReliableMessageMgr.h>
#include <messaging/ReliableMessageProtocolConfig.h>
#include <protocols/Protocols.h>
#include <protocols/echo/Echo.h>
#include <transport/SessionManager.h>
#include <transport/TransportMgr.h>

#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <messaging/tests/MessagingContext.h>

#if CHIP_CONFIG_ENABLE_ICD_SERVER
#include <app/icd/server/ICDConfigurationData.h> // nogncheck
#endif

#if CHIP_CRYPTO_PSA
#include "psa/crypto.h"
#endif

namespace {

using namespace chip;
using namespace chip::Inet;
using namespace chip::Transport;
using namespace chip::Messaging;
using namespace chip::Protocols;
using namespace chip::System::Clock::Literals;

const char PAYLOAD[] = "Hello!";

class TestReliablityAnalyticDelegate : public ReliableMessageAnalyticsDelegate
{
public:
    virtual void OnTransmitEvent(const TransmitEvent & event) override { mTransmitEvents.push(event); }
    std::queue<ReliableMessageAnalyticsDelegate::TransmitEvent> mTransmitEvents;
};

class TestReliableMessageProtocol : public chip::Testing::LoopbackMessagingContext
{
public:
    // Performs setup for each individual test in the test suite
    void SetUp() override
    {
#if CHIP_CRYPTO_PSA
        ASSERT_EQ(psa_crypto_init(), PSA_SUCCESS);
#endif
        chip::Testing::LoopbackMessagingContext::SetUp();
        GetSessionAliceToBob()->AsSecureSession()->SetRemoteSessionParameters(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig()));
        GetSessionBobToAlice()->AsSecureSession()->SetRemoteSessionParameters(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig()));
    }
};

class MockAppDelegate : public UnsolicitedMessageHandler, public ExchangeDelegate
{
public:
    MockAppDelegate(TestReliableMessageProtocol & ctx) : mTestReliableMessageProtocol(ctx) {}

    CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override
    {
        // Handle messages by myself
        newDelegate = this;
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR OnMessageReceived(ExchangeContext * ec, const PayloadHeader & payloadHeader,
                                 System::PacketBufferHandle && buffer) override
    {
        IsOnMessageReceivedCalled = true;

        if (ec->HasSessionHandle() && ec->GetSessionHolder()->IsSecureSession())
        {
            mLastSubjectDescriptor = ec->GetSessionHolder()->AsSecureSession()->GetSubjectDescriptor();
        }

        if (payloadHeader.IsAckMsg())
        {
            mReceivedPiggybackAck = true;
        }
        if (mDropAckResponse)
        {
            auto * rc = ec->GetReliableMessageContext();
            if (rc->HasPiggybackAckPending())
            {
                // Make sure we don't accidentally retransmit and end up acking
                // the retransmit.
                rc->GetReliableMessageMgr()->StopTimer();
                (void) rc->TakePendingPeerAckMessageCounter();
            }
        }

        if (mExchange != ec)
        {
            CloseExchangeIfNeeded();
        }

        if (!mRetainExchange)
        {
            ec = nullptr;
        }
        else
        {
            ec->WillSendMessage();
        }
        mExchange = ec;

        EXPECT_EQ(buffer->TotalLength(), sizeof(PAYLOAD));
        EXPECT_EQ(memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()), 0);

        return CHIP_NO_ERROR;
    }

    void OnResponseTimeout(ExchangeContext * ec) override { mResponseTimedOut = true; }

    void CloseExchangeIfNeeded()
    {
        if (mExchange != nullptr)
        {
            mExchange->Close();
            mExchange = nullptr;
        }
    }

    void SetDropAckResponse(bool dropResponse)
    {
        mDropAckResponse = dropResponse;
        if (!mDropAckResponse)
        {
            // Restart the MRP retransmit timer, now that we are not going to be
            // dropping acks anymore, so we send out pending retransmits, if
            // any, as needed.
            mTestReliableMessageProtocol.GetExchangeManager().GetReliableMessageMgr()->StartTimer();
        }
    }

    Access::SubjectDescriptor mLastSubjectDescriptor{};

    bool IsOnMessageReceivedCalled = false;
    bool mReceivedPiggybackAck     = false;
    bool mRetainExchange           = false;
    bool mResponseTimedOut         = false;
    ExchangeContext * mExchange    = nullptr;

private:
    TestReliableMessageProtocol & mTestReliableMessageProtocol;
    bool mDropAckResponse = false;
};

class MockSessionEstablishmentExchangeDispatch : public Messaging::ApplicationExchangeDispatch
{
public:
    bool IsReliableTransmissionAllowed() const override { return mRetainMessageOnSend; }

    bool MessagePermitted(Protocols::Id protocol, uint8_t type) override { return true; }

    bool IsEncryptionRequired() const override { return mRequireEncryption; }

    bool mRetainMessageOnSend = true;

    bool mRequireEncryption = false;
};

class MockSessionEstablishmentDelegate : public UnsolicitedMessageHandler, public ExchangeDelegate
{
public:
    CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override
    {
        // Handle messages by myself
        newDelegate = this;
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR OnMessageReceived(ExchangeContext * ec, const PayloadHeader & payloadHeader,
                                 System::PacketBufferHandle && buffer) override
    {
        IsOnMessageReceivedCalled = true;
        EXPECT_EQ(buffer->TotalLength(), sizeof(PAYLOAD));
        EXPECT_EQ(memcmp(buffer->Start(), PAYLOAD, buffer->TotalLength()), 0);
        return CHIP_NO_ERROR;
    }

    void OnResponseTimeout(ExchangeContext * ec) override {}

    virtual ExchangeMessageDispatch & GetMessageDispatch() override { return mMessageDispatch; }

    bool IsOnMessageReceivedCalled = false;
    MockSessionEstablishmentExchangeDispatch mMessageDispatch;
};

struct BackoffComplianceTestVector
{
    uint8_t sendCount;
    System::Clock::Timeout backoffBase;
    System::Clock::Timeout backoffMin;
    System::Clock::Timeout backoffMax;
};

struct BackoffComplianceTestVector theBackoffComplianceTestVector[] = { {
                                                                            .sendCount   = 0,
                                                                            .backoffBase = System::Clock::Timeout(300),
                                                                            .backoffMin  = System::Clock::Timeout(330),
                                                                            .backoffMax  = System::Clock::Timeout(413),
                                                                        },
                                                                        {
                                                                            .sendCount   = 1,
                                                                            .backoffBase = System::Clock::Timeout(300),
                                                                            .backoffMin  = System::Clock::Timeout(330),
                                                                            .backoffMax  = System::Clock::Timeout(413),
                                                                        },
                                                                        {
                                                                            .sendCount   = 2,
                                                                            .backoffBase = System::Clock::Timeout(300),
                                                                            .backoffMin  = System::Clock::Timeout(528),
                                                                            .backoffMax  = System::Clock::Timeout(661),
                                                                        },
                                                                        {
                                                                            .sendCount   = 3,
                                                                            .backoffBase = System::Clock::Timeout(300),
                                                                            .backoffMin  = System::Clock::Timeout(844),
                                                                            .backoffMax  = System::Clock::Timeout(1057),
                                                                        },
                                                                        {
                                                                            .sendCount   = 4,
                                                                            .backoffBase = System::Clock::Timeout(300),
                                                                            .backoffMin  = System::Clock::Timeout(1351),
                                                                            .backoffMax  = System::Clock::Timeout(1691),
                                                                        },
                                                                        {
                                                                            .sendCount   = 5,
                                                                            .backoffBase = System::Clock::Timeout(300),
                                                                            .backoffMin  = System::Clock::Timeout(2162),
                                                                            .backoffMax  = System::Clock::Timeout(2705),
                                                                        },
                                                                        {
                                                                            .sendCount   = 6,
                                                                            .backoffBase = System::Clock::Timeout(300),
                                                                            .backoffMin  = System::Clock::Timeout(2162),
                                                                            .backoffMax  = System::Clock::Timeout(2705),
                                                                        },
                                                                        {
                                                                            .sendCount   = 0,
                                                                            .backoffBase = System::Clock::Timeout(4000),
                                                                            .backoffMin  = System::Clock::Timeout(4400),
                                                                            .backoffMax  = System::Clock::Timeout(5503),
                                                                        },
                                                                        {
                                                                            .sendCount   = 1,
                                                                            .backoffBase = System::Clock::Timeout(4000),
                                                                            .backoffMin  = System::Clock::Timeout(4400),
                                                                            .backoffMax  = System::Clock::Timeout(5503),
                                                                        },
                                                                        {
                                                                            .sendCount   = 2,
                                                                            .backoffBase = System::Clock::Timeout(4000),
                                                                            .backoffMin  = System::Clock::Timeout(7040),
                                                                            .backoffMax  = System::Clock::Timeout(8805),
                                                                        },
                                                                        {
                                                                            .sendCount   = 3,
                                                                            .backoffBase = System::Clock::Timeout(4000),
                                                                            .backoffMin  = System::Clock::Timeout(11264),
                                                                            .backoffMax  = System::Clock::Timeout(14088),
                                                                        },
                                                                        {
                                                                            .sendCount   = 4,
                                                                            .backoffBase = System::Clock::Timeout(4000),
                                                                            .backoffMin  = System::Clock::Timeout(18022),
                                                                            .backoffMax  = System::Clock::Timeout(22541),
                                                                        },
                                                                        {
                                                                            .sendCount   = 5,
                                                                            .backoffBase = System::Clock::Timeout(4000),
                                                                            .backoffMin  = System::Clock::Timeout(28835),
                                                                            .backoffMax  = System::Clock::Timeout(36065),
                                                                        },
                                                                        {
                                                                            .sendCount   = 6,
                                                                            .backoffBase = System::Clock::Timeout(4000),
                                                                            .backoffMin  = System::Clock::Timeout(28835),
                                                                            .backoffMax  = System::Clock::Timeout(36065),
                                                                        },
                                                                        {
                                                                            // test theoretical worst-case 1-hour interval
                                                                            .sendCount   = 4,
                                                                            .backoffBase = System::Clock::Timeout(3'600'000),
                                                                            .backoffMin  = System::Clock::Timeout(16'220'160),
                                                                            .backoffMax  = System::Clock::Timeout(20'286'001),
                                                                        } };

void CheckGetBackoffImpl(System::Clock::Timeout additionalMRPBackoffTime)
{
    ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(additionalMRPBackoffTime));

    // Run 3x iterations to thoroughly test random jitter always results in backoff within bounds.
    for (uint32_t j = 0; j < 3; j++)
    {
        for (const auto & test : theBackoffComplianceTestVector)
        {
            System::Clock::Timeout backoff      = ReliableMessageMgr::GetBackoff(test.backoffBase, test.sendCount);
            System::Clock::Timeout extraBackoff = additionalMRPBackoffTime;

#if CHIP_CONFIG_ENABLE_ICD_SERVER
            // If running as an ICD, increase maxBackoff to account for the polling interval
            extraBackoff += ICDConfigurationData::GetInstance().GetFastPollingInterval();
#endif

            ChipLogProgress(Test, "Backoff base %" PRIu32 " extra %" PRIu32 " # %d: %" PRIu32, test.backoffBase.count(),
                            extraBackoff.count(), test.sendCount, backoff.count());

            EXPECT_GE(backoff, test.backoffMin + extraBackoff);
            EXPECT_LE(backoff, test.backoffMax + extraBackoff);
        }
    }

    ReliableMessageMgr::SetAdditionalMRPBackoffTime(NullOptional);
}

} // namespace

TEST_F(TestReliableMessageProtocol, CheckAddClearRetrans)
{
    MockAppDelegate mockAppDelegate(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockAppDelegate);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm     = GetExchangeManager().GetReliableMessageMgr();
    ReliableMessageContext * rc = exchange->GetReliableMessageContext();
    ASSERT_NE(rm, nullptr);
    ASSERT_NE(rc, nullptr);

    ReliableMessageMgr::RetransTableEntry * entry;

    EXPECT_SUCCESS(rm->AddToRetransTable(rc, &entry));
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    rm->ClearRetransTable(*entry);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    exchange->Close();
}

/**
 * Tests MRP retransmission logic with the following scenario:
 *
 *      DUT = sender, PEER = remote device
 *
 * 1) DUT configured to use sleepy peer parameters of active = 64ms, idle = 64ms
 * 2) DUT sends message attempt #1 to PEER
 *      - Force PEER to drop message
 *      - Observe DUT timeout with no ack
 *      - Confirm MRP backoff interval is correct
 * 3) DUT resends message attempt #2 to PEER
 *      - Force PEER to drop message
 *      - Observe DUT timeout with no ack
 *      - Confirm MRP backoff interval is correct
 * 4) DUT resends message attempt #3 to PEER
 *      - Force PEER to drop message
 *      - Observe DUT timeout with no ack
 *      - Confirm MRP backoff interval is correct
 * 5) DUT resends message attempt #4 to PEER
 *      - Force PEER to drop message
 *      - Observe DUT timeout with no ack
 *      - Confirm MRP backoff interval is correct
 * 6) DUT resends message attempt #5 to PEER
 *      - PEER to acknowledge message
 *      - Observe DUT signal successful reliable transmission
 */
TEST_F(TestReliableMessageProtocol, CheckResendApplicationMessage)
{
    BackoffComplianceTestVector * expectedBackoff;
    System::Clock::Timestamp now, startTime;
    System::Clock::Timeout timeoutTime, margin;
    margin = System::Clock::Timeout(15);

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockSender(*this);
    // TODO: temporarily create a SessionHandle from node id, will be fix in PR 3602
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        System::Clock::Timestamp(300), // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        System::Clock::Timestamp(300), // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    // Let's drop the initial message
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 4;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // Ensure the exchange stays open after we send (unlike the CheckCloseExchangeAndResendApplicationMessage case), by claiming to
    // expect a response.
    startTime = System::SystemClock().GetMonotonicTimestamp();
    err       = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the initial message was dropped and was added to retransmit table
    EXPECT_EQ(loopback.mNumMessagesToDrop, 3u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Wait for the initial message to fail (should take 330-413ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
    now         = System::SystemClock().GetMonotonicTimestamp();
    timeoutTime = now - startTime;
    ChipLogProgress(Test, "Attempt #1  Timeout : %" PRIu32 "ms", timeoutTime.count());
    expectedBackoff = &theBackoffComplianceTestVector[0];
    EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin);

    startTime = System::SystemClock().GetMonotonicTimestamp();
    DrainAndServiceIO();

    // Ensure the 1st retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Wait for the 1st retry to fail (should take 330-413ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
    now         = System::SystemClock().GetMonotonicTimestamp();
    timeoutTime = now - startTime;
    ChipLogProgress(Test, "Attempt #2  Timeout : %" PRIu32 "ms", timeoutTime.count());
    expectedBackoff = &theBackoffComplianceTestVector[1];
    EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin);

    startTime = System::SystemClock().GetMonotonicTimestamp();
    DrainAndServiceIO();

    // Ensure the 2nd retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 3u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 3u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Wait for the 2nd retry to fail (should take 528-660ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; });
    now         = System::SystemClock().GetMonotonicTimestamp();
    timeoutTime = now - startTime;
    ChipLogProgress(Test, "Attempt #3  Timeout : %" PRIu32 "ms", timeoutTime.count());
    expectedBackoff = &theBackoffComplianceTestVector[2];
    EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin);

    startTime = System::SystemClock().GetMonotonicTimestamp();
    DrainAndServiceIO();

    // Ensure the 3rd retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 4u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 4u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Wait for the 3rd retry to fail (should take 845-1056ms)
    GetIOContext().DriveIOUntil(1500_ms32, [&] { return loopback.mSentMessageCount >= 5; });
    now         = System::SystemClock().GetMonotonicTimestamp();
    timeoutTime = now - startTime;
    ChipLogProgress(Test, "Attempt #4  Timeout : %" PRIu32 "ms", timeoutTime.count());
    expectedBackoff = &theBackoffComplianceTestVector[3];
    EXPECT_GE(timeoutTime, expectedBackoff->backoffMin - margin);

    // Trigger final transmission
    DrainAndServiceIO();

    // Ensure the last retransmission was NOT dropped, and the retransmit table is empty, as we should have gotten an ack
    EXPECT_GE(loopback.mSentMessageCount, 5u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 4u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    exchange->Close();
}

TEST_F(TestReliableMessageProtocol, CheckCloseExchangeAndResendApplicationMessage)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockSender(*this);
    // TODO: temporarily create a SessionHandle from node id, will be fixed in PR 3602
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    // Let's drop the initial message
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 2;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was dropped, and was added to retransmit table
    EXPECT_EQ(loopback.mNumMessagesToDrop, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Wait for the first re-transmit (should take 64ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
    DrainAndServiceIO();

    // Ensure the retransmit message was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Wait for the second re-transmit (should take 64ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
    DrainAndServiceIO();

    // Ensure the retransmit message was NOT dropped, and the retransmit table is empty, as we should have gotten an ack
    EXPECT_GE(loopback.mSentMessageCount, 3u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckFailedMessageRetainOnSend)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockSessionEstablishmentDelegate mockSender;
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    mockSender.mMessageDispatch.mRetainMessageOnSend = false;
    // Let's drop the initial message
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 1;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was dropped
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);

    // Wait for the first re-transmit (should take 64ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
    DrainAndServiceIO();

    // Ensure the retransmit table is empty, as we did not provide a message to retain
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckUnencryptedMessageReceiveFailure)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    MockSessionEstablishmentDelegate mockReceiver;
    CHIP_ERROR err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    // Expect the received messages to be encrypted
    mockReceiver.mMessageDispatch.mRequireEncryption = true;

    MockSessionEstablishmentDelegate mockSender;
    ExchangeContext * exchange = NewUnauthenticatedExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    // We are sending a malicious packet, doesn't expect an ack
    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kNoAutoRequestAck));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Test that the message was actually sent (and not dropped)
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
    // Test that the message was dropped by the receiver
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckResendApplicationMessageWithPeerExchange)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    // Let's drop the initial message
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 1;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was dropped, and was added to retransmit table
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);

    // Wait for the first re-transmit (should take 64ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
    DrainAndServiceIO();

    // Ensure the retransmit message was not dropped, and is no longer in the retransmit table
    EXPECT_GE(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);
}

TEST_F(TestReliableMessageProtocol, CheckDuplicateMessageClosedExchange)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL
    }));

    // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    // Drop the ack, and also close the peer exchange
    mockReceiver.SetDropAckResponse(true);
    mockReceiver.mRetainExchange = false;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent
    // The ack was dropped, and message was added to the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Let's not drop the duplicate message
    mockReceiver.SetDropAckResponse(false);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);

    // Wait for the first re-transmit and ack (should take 64ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
    DrainAndServiceIO();

    // Ensure the retransmit message was sent and the ack was sent
    // and retransmit table was cleared
    EXPECT_EQ(loopback.mSentMessageCount, 3u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckDuplicateOldMessageClosedExchange)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL
    }));

    // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    // Drop the ack, and also close the peer exchange
    mockReceiver.SetDropAckResponse(true);
    mockReceiver.mRetainExchange = false;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent
    // The ack was dropped, and message was added to the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Now send CHIP_CONFIG_MESSAGE_COUNTER_WINDOW_SIZE + 2 messages to make
    // sure our original message is out of the message counter window.  These
    // messages can be sent withour MRP, because we are not expecting acks for
    // them anyway.
    size_t extraMessages = CHIP_CONFIG_MESSAGE_COUNTER_WINDOW_SIZE + 2;
    for (size_t i = 0; i < extraMessages; ++i)
    {
        buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
        EXPECT_FALSE(buffer.IsNull());

        ExchangeContext * newExchange = NewExchangeToAlice(&mockSender);
        ASSERT_NE(newExchange, nullptr);

        mockReceiver.mRetainExchange = false;

        // Ensure the retransmit table has our one message right now
        EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

        // Send without MRP.
        err = newExchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kNoAutoRequestAck);
        EXPECT_EQ(err, CHIP_NO_ERROR);
        DrainAndServiceIO();

        // Ensure the message was sent, but not added to the retransmit table.
        EXPECT_EQ(loopback.mSentMessageCount, 1u + (i + 1u));
        EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
        EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    }

    // Let's not drop the duplicate message's ack.
    mockReceiver.SetDropAckResponse(false);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);

    // Wait for the first re-transmit and ack (should take 64ms)
    rm->StartTimer();
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3 + extraMessages; });
    DrainAndServiceIO();

    // Ensure the retransmit message was sent and the ack was sent
    // and retransmit table was cleared
    EXPECT_EQ(loopback.mSentMessageCount, 3u + extraMessages);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckResendSessionEstablishmentMessageWithPeerExchange)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    ASSERT_FALSE(buffer.IsNull());

    MockSessionEstablishmentDelegate mockReceiver;
    CHIP_ERROR err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockSessionEstablishmentDelegate mockSender;
    ExchangeContext * exchange = NewUnauthenticatedExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    // Let's drop the initial message
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 1;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was dropped, and was added to retransmit table
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);

    // Wait for the first re-transmit (should take 64ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
    DrainAndServiceIO();

    // Ensure the retransmit message was not dropped, and is no longer in the retransmit table
    EXPECT_GE(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);
}

TEST_F(TestReliableMessageProtocol, CheckDuplicateMessage)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_RMP_DEFAULT_INITIAL_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_RMP_DEFAULT_ACTIVE_RETRY_INTERVAL
    }));

    // Let's not drop the message. Expectation is that it is received by the peer, but the ack is dropped
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    // Drop the ack, and keep the exchange around to receive the duplicate message
    mockReceiver.SetDropAckResponse(true);
    mockReceiver.mRetainExchange = true;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent
    // The ack was dropped, and message was added to the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);

    // Let's not drop the duplicate message
    mockReceiver.SetDropAckResponse(false);
    mockReceiver.mRetainExchange = false;

    // Wait for the first re-transmit and ack (should take 64ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
    DrainAndServiceIO();

    // Ensure the retransmit message was sent and the ack was sent
    // and retransmit table was cleared
    EXPECT_EQ(loopback.mSentMessageCount, 3u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    mockReceiver.CloseExchangeIfNeeded();
}

TEST_F(TestReliableMessageProtocol, CheckReceiveAfterStandaloneAck)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // We send a message, have it get received by the peer, then an ack is
    // returned, then a reply is returned.  We need to keep the receiver
    // exchange alive until it does the message send (so we can send the
    // response from the receiver and so the initial sender exchange can get
    // it).
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;
    mockReceiver.mRetainExchange  = true;

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that it was received.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);

    // And that we have not seen an ack yet.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
    EXPECT_TRUE(receiverRc->IsAckPending());

    // Send the standalone ack.
    EXPECT_SUCCESS(receiverRc->SendStandaloneAckMessage());
    DrainAndServiceIO();

    // Ensure the ack was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // Ensure that we have not gotten any app-level responses so far.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);

    // And that we have now gotten our ack.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // Now send a message from the other side.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the response and its ack was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 4u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // Ensure that we have received that response.
    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);

    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckPiggybackAfterPiggyback)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // We send a message, have it get received by the peer, have the peer return
    // a piggybacked ack.  Then we send a second message this time _not_
    // requesting an ack, get a response, and see whether an ack was
    // piggybacked.  We need to keep both exchanges alive for that (so we can
    // send the response from the receiver and so the initial sender exchange
    // can get it).
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;
    mockReceiver.mRetainExchange  = true;
    mockSender.mRetainExchange    = true;

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that it was received.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);

    // And that we have not seen an ack yet.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
    EXPECT_TRUE(receiverRc->IsAckPending());

    // Ensure that we have not gotten any app-level responses or acks so far.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockSender.mReceivedPiggybackAck);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Now send a message from the other side.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err =
        mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer),
                                            SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the response was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // Ensure that we have received that response and it had a piggyback ack.
    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_TRUE(mockSender.mReceivedPiggybackAck);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // Reset various state so we can measure things again.
    mockReceiver.IsOnMessageReceivedCalled = false;
    mockSender.IsOnMessageReceivedCalled   = false;
    mockSender.mReceivedPiggybackAck       = false;

    // Now send a new message to the other side, but don't ask for an ack.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer),
                                SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 3u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that it was received.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);

    // And that we are not expecting an ack.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // Send the final response.  At this point we don't need to keep the
    // exchanges alive anymore.
    mockReceiver.mRetainExchange = false;
    mockSender.mRetainExchange   = false;

    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the response and its ack was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 5u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // Ensure that we have received that response and it had a piggyback ack.
    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_TRUE(mockSender.mReceivedPiggybackAck);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);

    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckSendUnsolicitedStandaloneAckMessage)
{
    /**
     * Tests sending a standalone ack message that is:
     * 1) Unsolicited.
     * 2) Requests an ack.
     *
     * This is not a thing that would normally happen, but a malicious entity
     * could absolutely do this.
     */
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData("", 0);
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // We send a message, have it get received by the peer, expect an ack from
    // the peer.
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    // Purposefully sending a standalone ack that requests an ack!
    err = exchange->SendMessage(SecureChannel::MsgType::StandaloneAck, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    // Needs a manual close, because SendMessage does not close for standalone acks.
    exchange->Close();
    DrainAndServiceIO();

    // Ensure the message and its ack were sent.
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that nothing is waiting for acks.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckSendStandaloneAckMessage)
{
    MockAppDelegate mockAppDelegate(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockAppDelegate);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm     = GetExchangeManager().GetReliableMessageMgr();
    ReliableMessageContext * rc = exchange->GetReliableMessageContext();
    ASSERT_NE(rm, nullptr);
    ASSERT_NE(rc, nullptr);

    EXPECT_EQ(rc->SendStandaloneAckMessage(), CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Need manual close because standalone acks don't close exchanges.
    exchange->Close();
}

TEST_F(TestReliableMessageProtocol, CheckMessageAfterClosed)
{
    /**
     * This test performs the following sequence of actions, where all messages
     * are sent with MRP enabled:
     *
     * 1) Initiator sends message to responder.
     * 2) Responder responds to the message (piggybacking an ack) and closes
     *    the exchange.
     * 3) Initiator sends a response to the response on the same exchange, again
     *    piggybacking an ack.
     *
     * This is basically the "command, response, status response" flow, with the
     * responder closing the exchange after it sends the response.
     */

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;
    // We need to keep both exchanges alive for the thing we are testing here.
    mockReceiver.mRetainExchange = true;
    mockSender.mRetainExchange   = true;

    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockReceiver.mReceivedPiggybackAck);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that it was received.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockReceiver.mReceivedPiggybackAck);

    // And that we have not seen an ack yet.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
    EXPECT_TRUE(receiverRc->IsAckPending());

    // Ensure that we have not gotten any app-level responses or acks so far.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockSender.mReceivedPiggybackAck);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Now send a message from the other side.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the response was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // Ensure that we have received that response and it had a piggyback ack.
    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_TRUE(mockSender.mReceivedPiggybackAck);
    // And that we are now waiting for an ack for the response.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Reset various state so we can measure things again.
    mockReceiver.IsOnMessageReceivedCalled = false;
    mockReceiver.mReceivedPiggybackAck     = false;
    mockSender.IsOnMessageReceivedCalled   = false;
    mockSender.mReceivedPiggybackAck       = false;

    // Now send a second message to the other side.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent (and the ack for it was also sent).
    EXPECT_EQ(loopback.mSentMessageCount, 4u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that it was not received (because the exchange is closed on the
    // receiver).
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);

    // And that we are not expecting an ack; acks should have been flushed
    // immediately on the receiver, due to the exchange being closed.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);

    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckLostResponseWithPiggyback)
{
    /**
     * This tests the following scenario:
     * 1) A reliable message is sent from initiator to responder.
     * 2) The responder sends a response with a piggybacked ack, which is lost.
     * 3) Initiator resends the message.
     * 4) Responder responds to the resent message with a standalone ack.
     * 5) The responder retransmits the application-level response.
     * 4) The initiator should receive the application-level response.
     */
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // Make sure that we resend our message before the other side does.
    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    // We send a message, the other side sends an application-level response
    // (which is lost), then we do a retransmit that is acked, then the other
    // side does a retransmit.  We need to keep the receiver exchange alive (so
    // we can send the response from the receiver), but don't need anything
    // special for the sender exchange, because it will be waiting for the
    // application-level response.
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;
    mockReceiver.mRetainExchange  = true;

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that it was received.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);

    // And that we have not gotten any app-level responses or acks so far.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
    // Should have pending ack here.
    EXPECT_TRUE(receiverRc->IsAckPending());
    // Make sure receiver resends after sender does, and there's enough of a gap
    // that we are very unlikely to actually trigger the resends on the receiver
    // when we trigger the resends on the sender.
    mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        256_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        256_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    // Now send a message from the other side, but drop it.
    loopback.mNumMessagesToDrop = 1;

    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    // Stop keeping receiver exchange alive.
    mockReceiver.mRetainExchange = true;

    err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the response was sent but dropped.
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);

    // Ensure that we have not received that response.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockSender.mReceivedPiggybackAck);
    // We now have our un-acked message still waiting to retransmit and the
    // message that the other side sent is waiting for an ack.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 2);

    // Reset various state so we can measure things again.
    mockReceiver.IsOnMessageReceivedCalled = false;
    mockReceiver.mReceivedPiggybackAck     = false;
    mockSender.IsOnMessageReceivedCalled   = false;
    mockSender.mReceivedPiggybackAck       = false;

    // Wait for re-transmit from sender and ack (should take 64ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; });
    DrainAndServiceIO();

    // We resent our first message, which did not make it to the app-level
    // listener on the receiver (because it's a duplicate) but did trigger a
    // standalone ack.
    //
    // Now the annoying part is that depending on how long we _actually_ slept
    // we might have also triggered the retransmit from the other side, even
    // though we did not want to.  Handle both cases here.
    EXPECT_TRUE(loopback.mSentMessageCount == 4 || loopback.mSentMessageCount == 6);
    if (loopback.mSentMessageCount == 4)
    {
        // Just triggered the retransmit from the sender.
        EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
        EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
        EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
        EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    }
    else
    {
        // Also triggered the retransmit from the receiver.
        EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
        EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
        EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
        EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
    }

    // Wait for re-transmit from receiver (should take 256ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 6; });
    DrainAndServiceIO();

    // And now we've definitely resent our response message, which should show
    // up as an app-level message and trigger a standalone ack.
    EXPECT_EQ(loopback.mSentMessageCount, 6u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);

    // Should be all done now.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckIsPeerActiveNotInitiator)
{
    /**
     * This tests the following scenario:
     * 1) A reliable message expecting a response is sent from the initiator to responder which is lost
     * 2) Initiator resends the message at the IdleRetrans interval
     * 3) Responder receives the message and sends a standalone ack
     * 4) Responder sends a response and fails
     * 5) Responder retries at the ActiveRestrans interval
     * 6) Initiator receives the response
     */

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        1000_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        1000_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 1;
    loopback.mDroppedMessageCount = 0;

    mockReceiver.mRetainExchange = true;
    mockSender.mRetainExchange   = true;

    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Verify that the first message is dropped
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);

    // Make sure retransmit was not done before the idle restrans interval hits
    GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 1; });
    DrainAndServiceIO();

    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());

    // // Make sure nothing happened
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);

    // // Retrasnmit message
    GetIOContext().DriveIOUntil(2000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
    DrainAndServiceIO();

    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());

    // // Make sure nothing happened
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);

    // // Verify that the receiver considers the sender is active
    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());
    EXPECT_TRUE(mockReceiver.mExchange->HasReceivedAtLeastOneMessage());

    mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        1000_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        100_ms32,  // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    mockReceiver.mRetainExchange = false;
    mockSender.mRetainExchange   = false;

    // Now send a message from the other side.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    // Make receiver message fail once
    loopback.mNumMessagesToDrop = 1;

    err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Make sure nothing happened
    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mSentMessageCount, 3u);
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);

    // // Retrasnmit message
    GetIOContext().DriveIOUntil(500_ms32, [&] { return loopback.mSentMessageCount >= 4; });
    DrainAndServiceIO();

    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_EQ(loopback.mSentMessageCount, 5u);
}

// =============================================================================
// ICD-aware MRP retransmit backoff tests
//
// These exercise ReliableMessageMgr::CalculateNextRetransTime's choice of base
// timeout (Active vs Idle) for an exchange where the peer is an Intermittently
// Connected Device (ICD) advertising a Session Active Threshold (SAT) much
// shorter than its Slow Idle Interval (SII).
//
// Per Matter Core spec §4.11.2.1 Retransmissions and §4.12 Intermittently
// Connected Devices, the controller must spread retransmissions on the Idle
// interval (SII) once the peer has dropped out of its Active window — even if
// the local exchange has received messages from the peer earlier in the
// exchange.
//
// Bug being guarded:
//   A prior shortcut in CalculateNextRetransTime pinned to mActiveRetransTimeout
//   (SAI) for the rest of the exchange as soon as HasReceivedAtLeastOneMessage()
//   was true. For an ICD whose SAT < first-retx-backoff that meant every retx
//   landed inside the peer's sleep window and reliable delivery silently failed
//   (e.g. CASE Sigma3 to a sleepy Thread accessory).
//
// Test pattern (modeled after CheckIsPeerActiveNotInitiator above):
//   Each test sends with kExpectResponse, drops one or more sends, then lets
//   the retransmit succeed so the exchange closes naturally before TearDown.
//   This avoids leaving an exchange in a "waiting for response" state, which
//   would trip CancelResponseTimer through a torn-down SessionManager during
//   shutdown.
// =============================================================================

namespace {

// Helper: build an ICD-like peer MRP config.
//
//   SII = 1500 ms — Idle retx baseline; tests probing the post-SAT path
//                    assert retx fires no sooner than this (after margin).
//   SAI =  100 ms — Active retx baseline; tests of the pre-SAT-expiry path
//                    assert retx fires well under this baseline + jitter.
//   sat — Session Active Threshold; varied per test so we can stay inside
//         the Active window or step outside it.
ReliableMessageProtocolConfig MakeICDLikeMRPConfig(System::Clock::Milliseconds16 sat)
{
    return ReliableMessageProtocolConfig(1500_ms32, // mIdleRetransTimeout (SII)
                                         100_ms32,  // mActiveRetransTimeout (SAI)
                                         sat        // mActiveThresholdTime (SAT)
    );
}

// Wall-clock tolerance for backoff timing assertions. MRP backoff adds up to
// ~25% jitter on top of the (margin-adjusted) base, so a 50 ms lower-bound
// margin keeps the tests stable on slow CI runners while still cleanly
// distinguishing SAI- and SII-derived retx spacing.
//
// All tests in this file that consume these constants force the additional
// MRP sender boost to 0 via ReliableMessageMgr::SetAdditionalMRPBackoffTime.
// The platform default (CHIP_CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST = 1500ms
// on OpenThread/non-Linux, 0 elsewhere) would otherwise shift these bounds
// in a platform-dependent way.
constexpr System::Clock::Milliseconds32 kMrpTimingMargin = 50_ms32;

// SII-derived lower bound for "this retx was scheduled on Idle". Bottom of
// the jitter range for SII × margin × backoff^0 — for our SII=1500ms config
// (with sender boost forced to 0), the minimum is at least SII itself.
constexpr System::Clock::Milliseconds32 kIdleRetxMinElapsed = 1500_ms32;

// Upper fence for "this retx was scheduled on Active". With our SAI=100ms
// config and sender boost forced to 0, an Active retx fires within a few
// hundred ms of the original send; 1200 ms gives plenty of room for jitter
// and CI noise while remaining well below kIdleRetxMinElapsed (1500 ms) so
// the two regimes can't be confused.
constexpr System::Clock::Milliseconds32 kActiveRetxMaxElapsed = 1200_ms32;

} // namespace

/**
 * Verifies that once the peer's Session Active Threshold has elapsed, the
 * responder's retransmissions of a subsequent reliable message are spaced on
 * the IDLE interval (SII), even though the exchange has received at least one
 * message from the peer earlier.
 *
 * Pattern:
 *   1) Alice (initiator) sends EchoRequest to Bob with kExpectResponse.
 *   2) Bob's exchange receives it; mockReceiver retains the exchange so we
 *      can drive a response from it later. Bob's exchange now has
 *      HasReceivedAtLeastOneMessage() = true, and Bob's session for Alice
 *      has fresh mLastPeerActivityTime.
 *   3) We configure Bob's view of Alice as an ICD-like sleepy peer with
 *      SAT=50ms, and wait 200ms — well past SAT. IsPeerActive() for Alice
 *      on Bob's session is now false.
 *   4) Bob sends EchoResponse back to Alice; loopback drops it once.
 *   5) Bob's MRP must schedule the retx on the Idle interval (SII=1500ms),
 *      not the Active interval (SAI=100ms). The retx is allowed to succeed,
 *      Alice receives the response, and the exchange closes naturally.
 *   6) Verify timing: measured retx elapsed >= SII floor minus margin.
 *   7) Verify clean shutdown: retransmit table is empty and Alice's
 *      delegate observed the EchoResponse.
 */
TEST_F(TestReliableMessageProtocol, CheckICDPeerRetxUsesIdleBackoffAfterSATExpiry)
{
    // Force the additional MRP sender boost to 0 for the duration of this test so the timing
    // bounds below are independent of the platform default (CHIP_CONFIG_MRP_RETRY_INTERVAL_SENDER_BOOST
    // is 1500ms on OpenThread/non-Linux, 0 elsewhere). Reset at the bottom of the test.
    ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(System::Clock::Timeout(0)));

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    mockReceiver.mRetainExchange = true;
    mockSender.mRetainExchange   = true;

    // 1) Alice → Bob, expecting a response. Clean delivery — Bob acks via the
    //    EchoResponse we drive in step 4.
    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();
    ASSERT_NE(mockReceiver.mExchange, nullptr);
    EXPECT_TRUE(mockReceiver.mExchange->HasReceivedAtLeastOneMessage());

    // 2) Configure Bob's session view of Alice as an ICD-like sleepy peer.
    mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(
        MakeICDLikeMRPConfig(50_ms16 /* SAT */));

    // 3) Step past SAT so IsPeerActive() returns false on Bob's session.
    GetIOContext().DriveIOUntil(200_ms32, [&] { return false; });
    DrainAndServiceIO();
    EXPECT_FALSE(mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->IsPeerActive());

    mockReceiver.mRetainExchange = false;
    mockSender.mRetainExchange   = false;

    // 4) Bob sends EchoResponse; loopback drops it once. The retx is allowed
    //    to succeed on the second send.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());
    loopback.mNumMessagesToDrop      = 1;
    uint32_t sentCountBeforeResponse = loopback.mSentMessageCount;

    System::Clock::Timestamp txTime = System::SystemClock().GetMonotonicTimestamp();
    err                             = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(loopback.mSentMessageCount, sentCountBeforeResponse + 1u);
    // After Bob's EchoResponse drop, the retransmit table holds Bob's entry
    // plus (typically) Alice's prior EchoRequest entry whose piggybacked ack
    // was carried on the dropped EchoResponse. Don't pin the exact count.
    EXPECT_GE(rm->TestGetCountRetransTable(), 1);

    // 5) Wait long enough for the SII-derived retx to fire AND complete. We
    //    poll until the message-count grows past the post-send baseline; in
    //    the bug we'd see this in well under 200 ms (SAI-derived), in the
    //    fixed path the soonest possible time is ~kIdleRetxMinElapsed.
    GetIOContext().DriveIOUntil(3000_ms32, [&] { return mockSender.IsOnMessageReceivedCalled; });
    DrainAndServiceIO();

    System::Clock::Timestamp now              = System::SystemClock().GetMonotonicTimestamp();
    System::Clock::Milliseconds64 elapsedMs64 = now - txTime;
    auto elapsedMs                            = System::Clock::Milliseconds32(static_cast<uint32_t>(elapsedMs64.count()));
    ChipLogProgress(Test, "ICD retx fired and was delivered at %" PRIu32 "ms (expected >= %" PRIu32 "ms)", elapsedMs.count(),
                    (kIdleRetxMinElapsed - kMrpTimingMargin).count());

    // 6) Timing assertion.
    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_GE(elapsedMs.count(), (kIdleRetxMinElapsed - kMrpTimingMargin).count());

    // 7) Clean shutdown: nothing should remain in the retransmit table.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    ReliableMessageMgr::SetAdditionalMRPBackoffTime(NullOptional);
}

/**
 * Inverse of the test above. Verifies that the SAI-fast-path is still in
 * effect when the peer IS within its Active window: retx is spaced on SAI,
 * not SII. Guards against an over-broad fix that always uses SII regardless
 * of peer state.
 */
TEST_F(TestReliableMessageProtocol, CheckICDPeerRetxUsesActiveBackoffWithinSATWindow)
{
    // Force the additional MRP sender boost to 0 (see CheckICDPeerRetxUsesIdleBackoffAfterSATExpiry
    // for rationale). Reset at the bottom of the test.
    ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(System::Clock::Timeout(0)));

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    mockReceiver.mRetainExchange = true;
    mockSender.mRetainExchange   = true;

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();
    ASSERT_NE(mockReceiver.mExchange, nullptr);
    EXPECT_TRUE(mockReceiver.mExchange->HasReceivedAtLeastOneMessage());

    // ICD-like config but with a LARGE SAT (2 seconds) so the peer stays
    // Active for the entire test.
    mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(
        MakeICDLikeMRPConfig(2000_ms16 /* SAT — well above the test runtime */));
    EXPECT_TRUE(mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->IsPeerActive());

    mockReceiver.mRetainExchange = false;
    mockSender.mRetainExchange   = false;

    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());
    loopback.mNumMessagesToDrop      = 1;
    uint32_t sentCountBeforeResponse = loopback.mSentMessageCount;

    System::Clock::Timestamp txTime = System::SystemClock().GetMonotonicTimestamp();
    err                             = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(loopback.mSentMessageCount, sentCountBeforeResponse + 1u);
    EXPECT_GE(rm->TestGetCountRetransTable(), 1);

    // Drive IO until the retx completes; expected well below the Idle floor.
    GetIOContext().DriveIOUntil(kActiveRetxMaxElapsed, [&] { return mockSender.IsOnMessageReceivedCalled; });
    DrainAndServiceIO();

    System::Clock::Timestamp now              = System::SystemClock().GetMonotonicTimestamp();
    System::Clock::Milliseconds64 elapsedMs64 = now - txTime;
    auto elapsedMs                            = System::Clock::Milliseconds32(static_cast<uint32_t>(elapsedMs64.count()));
    ChipLogProgress(Test, "Active retx fired and was delivered at %" PRIu32 "ms (expected <= %" PRIu32 "ms)", elapsedMs.count(),
                    kActiveRetxMaxElapsed.count());

    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_LE(elapsedMs.count(), kActiveRetxMaxElapsed.count());
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    ReliableMessageMgr::SetAdditionalMRPBackoffTime(NullOptional);
}

/**
 * Exchange has NOT received any messages yet (HasReceivedAtLeastOneMessage =
 * false), AND the test has explicitly stepped past SAT so IsPeerActive()
 * returns false. Under those conditions the retx must be scheduled on the
 * IDLE interval. Confirms the pre-existing else-branch behavior survives the
 * simplification — the pre-fix shortcut never fired here either (it required
 * HasReceivedAtLeastOneMessage to be true), but the post-fix code path now
 * handles all retx scheduling, so this case still needs to be pinned.
 *
 * Alice sends a reliable EchoRequest (without kExpectResponse, so no
 * response timer is left dangling at TearDown). Loopback drops the first
 * attempt. The retransmit is allowed to succeed, Bob's MRP standalone ack
 * reaches Alice and clears her retransmit entry. The retransmit table
 * draining is the success signal; total elapsed time-to-drain must be
 * >= the SII-derived floor.
 */
TEST_F(TestReliableMessageProtocol, CheckPeerRetxUsesIdleBackoffWhenNoMessagesReceived)
{
    // Force the additional MRP sender boost to 0 (see CheckICDPeerRetxUsesIdleBackoffAfterSATExpiry
    // for rationale). Reset at the bottom of the test.
    ReliableMessageMgr::SetAdditionalMRPBackoffTime(MakeOptional(System::Clock::Timeout(0)));

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    // ICD-like config with a very short SAT so we can step past it cheaply. SecureSession
    // initializes mLastPeerActivityTime to the session-creation timestamp, so a fresh session
    // is implicitly Active for SAT milliseconds even before the first received message. The
    // test's premise — Idle backoff for an exchange with no prior receives — only holds once
    // SAT has elapsed against that initial timestamp.
    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(MakeICDLikeMRPConfig(50_ms16 /* SAT */));

    // Step past SAT so IsPeerActive() returns false on the sending session.
    GetIOContext().DriveIOUntil(150_ms32, [&] { return false; });
    DrainAndServiceIO();
    EXPECT_FALSE(exchange->GetSessionHandle()->AsSecureSession()->IsPeerActive());

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 1;
    loopback.mDroppedMessageCount = 0;

    // The exchange has NOT received any messages from the peer (`HasReceivedAtLeastOneMessage`
    // is false), and SAT has elapsed so the session is Idle. The pre-fix code's shortcut path
    // didn't apply here (it required `HasReceivedAtLeastOneMessage` to be true), so this case
    // already behaved correctly; the test pins that behavior under the simplified code path.
    EXPECT_FALSE(exchange->HasReceivedAtLeastOneMessage());

    System::Clock::Timestamp txTime = System::SystemClock().GetMonotonicTimestamp();
    // No kExpectResponse: Alice does not need (and must not leave dangling) a
    // response timer for this test. Bob receives the EchoRequest, sends a
    // standalone ack, and the exchange tears down naturally once the ack
    // clears Alice's MRP retransmit entry.
    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_GE(rm->TestGetCountRetransTable(), 1);

    // Drive IO until Bob's standalone ack has reached Alice and her entry has
    // been cleared (retransmit table drains to 0). With Idle spacing the
    // retx fires no sooner than ~kIdleRetxMinElapsed, plus the small ack
    // round-trip; in the buggy SAI path it would fire in well under 200 ms.
    GetIOContext().DriveIOUntil(3000_ms32, [&] { return rm->TestGetCountRetransTable() == 0; });
    DrainAndServiceIO();

    System::Clock::Timestamp now              = System::SystemClock().GetMonotonicTimestamp();
    System::Clock::Milliseconds64 elapsedMs64 = now - txTime;
    auto elapsedMs                            = System::Clock::Milliseconds32(static_cast<uint32_t>(elapsedMs64.count()));
    ChipLogProgress(Test, "Initial Idle retx drained at %" PRIu32 "ms (expected >= %" PRIu32 "ms)", elapsedMs.count(),
                    (kIdleRetxMinElapsed - kMrpTimingMargin).count());

    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
    EXPECT_GE(elapsedMs.count(), (kIdleRetxMinElapsed - kMrpTimingMargin).count());

    ReliableMessageMgr::SetAdditionalMRPBackoffTime(NullOptional);
}

TEST_F(TestReliableMessageProtocol, CheckLostStandaloneAck)
{
    /**
     * This tests the following scenario:
     * 1) A reliable message is sent from initiator to responder.
     * 2) The responder sends a standalone ack, which is lost.
     * 3) The responder sends an application-level response.
     * 4) The initiator sends a reliable response to the app-level response.
     *
     * This should succeed, with all application-level messages being delivered
     * and no crashes.
     */
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    CHIP_ERROR err = CHIP_NO_ERROR;

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    // We send a message, the other side sends a standalone ack first (which is
    // lost), then an application response, then we respond to that response.
    // We need to keep both exchanges alive for that (so we can send the
    // response from the receiver and so the initial sender exchange can send a
    // response to that).
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;
    mockReceiver.mRetainExchange  = true;
    mockSender.mRetainExchange    = true;

    // And ensure the ack heading back our way is dropped.
    mockReceiver.SetDropAckResponse(true);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that it was received.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);

    // And that we have not gotten any app-level responses or acks so far.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    ReliableMessageContext * receiverRc = mockReceiver.mExchange->GetReliableMessageContext();
    // Ack should have been dropped.
    EXPECT_FALSE(receiverRc->IsAckPending());

    // Don't drop any more acks.
    mockReceiver.SetDropAckResponse(false);

    // Now send a message from the other side.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer),
                                              SendFlags(SendMessageFlags::kExpectResponse));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the response was sent.
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // Ensure that we have received that response and had a piggyback ack.
    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);
    EXPECT_TRUE(mockSender.mReceivedPiggybackAck);
    // We now have just the received message waiting for an ack.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // And receiver still has no ack pending.
    EXPECT_FALSE(receiverRc->IsAckPending());

    // Reset various state so we can measure things again.
    mockReceiver.IsOnMessageReceivedCalled = false;
    mockReceiver.mReceivedPiggybackAck     = false;
    mockSender.IsOnMessageReceivedCalled   = false;
    mockSender.mReceivedPiggybackAck       = false;

    // Stop retaining the recipient exchange.
    mockReceiver.mRetainExchange = false;

    // Now send a new message to the other side.
    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message and the standalone ack to it were sent.
    EXPECT_EQ(loopback.mSentMessageCount, 4u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    // And that it was received.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled);
    EXPECT_TRUE(mockReceiver.mReceivedPiggybackAck);

    // At this point all our exchanges and reliable message contexts should be
    // dead, so we can't test anything about their state.

    // And that there are no un-acked messages left.
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);
}

TEST_F(TestReliableMessageProtocol, CheckGetBackoff)
{
    CheckGetBackoffImpl(System::Clock::kZero);
}

TEST_F(TestReliableMessageProtocol, CheckGetBackoffAdditionalTime)
{
    CheckGetBackoffImpl(System::Clock::Seconds32(1));
}

TEST_F(TestReliableMessageProtocol, CheckApplicationResponseDelayed)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    // Make sure we are using CASE sessions, because there is no defunct-marking for PASE.
    ExpireSessionBobToAlice();
    ExpireSessionAliceToBob();
    err = CreateCASESessionBobToAlice();
    EXPECT_EQ(err, CHIP_NO_ERROR);
    err = CreateCASESessionAliceToBob();
    EXPECT_EQ(err, CHIP_NO_ERROR);

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    mockReceiver.mRetainExchange = true;

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    constexpr uint32_t kMaxMRPTransmits = 5; // Counting the initial message.

    // Let's drop all but the last MRP transmit.
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = kMaxMRPTransmits - 1;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    exchange->SetResponseTimeout(5000_ms32);
    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was dropped, and was added to retransmit table
    EXPECT_EQ(loopback.mNumMessagesToDrop, kMaxMRPTransmits - 2u);
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);

    // Wait for all but the last retransmit to happen.
    GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; });
    DrainAndServiceIO();

    // Ensure that nothing has been sent yet.
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);

    // Now allow through the next message (our last retransmit), but make sure
    // there is no standalone ack for it.
    mockReceiver.SetDropAckResponse(true);
    GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
    DrainAndServiceIO();

    // Verify that message was sent and received but nothing else has been sent.
    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);        // We have no ack yet.
    ASSERT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got the message.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.

    // It was not a commissioning CASE session so that is lined-up properly.
    EXPECT_FALSE(mockReceiver.mLastSubjectDescriptor.isCommissioning);

    // Ensure there will be no more weirdness with acks and that our MRP timer is restarted properly.
    mockReceiver.SetDropAckResponse(false);

    // Now send a response, but drop all but the last MRP retransmit.
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = kMaxMRPTransmits - 1;
    loopback.mDroppedMessageCount = 0;

    mockReceiver.mExchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // At this point, we should have two MRP contexts pending.
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 2);        // We have no ack yet.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.

    // Now wait for all but the last retransmit to happen from the other side.
    GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits - 1; });
    DrainAndServiceIO();

    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
    // We might have timed our MRP resends out, or not, but the other side is waiting for an ack.
    EXPECT_TRUE(rm->TestGetCountRetransTable() == 1 || rm->TestGetCountRetransTable() == 2);
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.

    // Now wait for us to time out our MRP context for sure.
    GetIOContext().DriveIOUntil(5000_ms32, [&] { return rm->TestGetCountRetransTable() == 1; });
    DrainAndServiceIO();

    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);        // We timed out our MRP context.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
    EXPECT_FALSE(mockSender.mResponseTimedOut);          // We did not time out yet.

    // Now wait for the last retransmit (and our ack) to to happen.
    GetIOContext().DriveIOUntil(5000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
    DrainAndServiceIO();

    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits + 1);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);        // Everything has been acked.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
    EXPECT_TRUE(mockSender.IsOnMessageReceivedCalled);   // We got the response.
    EXPECT_FALSE(mockSender.mResponseTimedOut);          // We did not time out yet.

    // Ensure that we did not mark any sessions defunct.
    EXPECT_FALSE(GetSessionBobToAlice()->AsSecureSession()->IsDefunct());
    EXPECT_FALSE(GetSessionAliceToBob()->AsSecureSession()->IsDefunct());

    // Reset our sessions, so other tests get the usual PASE session
    ExpireSessionBobToAlice();
    ExpireSessionAliceToBob();
    err = CreateSessionBobToAlice();
    EXPECT_EQ(err, CHIP_NO_ERROR);
    err = CreateSessionAliceToBob();
    EXPECT_EQ(err, CHIP_NO_ERROR);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);
}

TEST_F(TestReliableMessageProtocol, CheckApplicationResponseNeverComes)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    // Make sure we are using CASE sessions, because there is no defunct-marking for PASE.
    ExpireSessionBobToAlice();
    ExpireSessionAliceToBob();
    err = CreateCASESessionBobToAlice();
    EXPECT_EQ(err, CHIP_NO_ERROR);
    err = CreateCASESessionAliceToBob();
    EXPECT_EQ(err, CHIP_NO_ERROR);

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    MockAppDelegate mockReceiver(*this);
    err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    constexpr uint32_t kMaxMRPTransmits = 5; // Counting the initial message.

    // Let's drop all but the last MRP transmit.
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = kMaxMRPTransmits - 1;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    exchange->SetResponseTimeout(4000_ms32);
    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the message was dropped, and was added to retransmit table
    EXPECT_EQ(loopback.mNumMessagesToDrop, kMaxMRPTransmits - 2u);
    EXPECT_EQ(loopback.mSentMessageCount, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);

    // Wait for all but the last retransmit to happen.
    GetIOContext().DriveIOUntil(2000_ms32, [&] { return loopback.mDroppedMessageCount >= kMaxMRPTransmits - 1; });
    DrainAndServiceIO();

    // Ensure that nothing has been sent yet.
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits - 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    EXPECT_FALSE(mockReceiver.IsOnMessageReceivedCalled);
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);

    // Now allow through the next message (our last retransmit), but make sure
    // there is no standalone ack for it.
    mockReceiver.SetDropAckResponse(true);
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= kMaxMRPTransmits; });
    DrainAndServiceIO();

    // Verify that message was sent and received but nothing else has been sent.
    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);        // We have no ack yet.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got the message.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.

    // Ensure there will be no more weirdness with acks and that our MRP timer is restarted properly.
    mockReceiver.SetDropAckResponse(false);

    // Now wait for us to time out our MRP context.
    GetIOContext().DriveIOUntil(5000_ms32, [&] { return rm->TestGetCountRetransTable() == 0; });
    DrainAndServiceIO();

    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);        // We timed out our MRP context.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We did not get a response.
    EXPECT_FALSE(mockSender.mResponseTimedOut);          // We did not time out yet.

    // Now wait for our exchange to time out.
    GetIOContext().DriveIOUntil(3000_ms32, [&] { return mockSender.mResponseTimedOut; });
    DrainAndServiceIO();

    EXPECT_EQ(loopback.mSentMessageCount, kMaxMRPTransmits);
    EXPECT_EQ(loopback.mDroppedMessageCount, kMaxMRPTransmits - 1);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);        // We timed this out long ago.
    EXPECT_TRUE(mockReceiver.IsOnMessageReceivedCalled); // Other side got original message.
    EXPECT_FALSE(mockSender.IsOnMessageReceivedCalled);  // We never got a response.
    EXPECT_TRUE(mockSender.mResponseTimedOut);           // We tiemd out

    // We should have marked out session defunct.
    EXPECT_TRUE(GetSessionBobToAlice()->AsSecureSession()->IsDefunct());
    // Other side had no reason to mark its session defunct.
    EXPECT_FALSE(GetSessionAliceToBob()->AsSecureSession()->IsDefunct());

    // Reset our sessions, so other tests get the usual PASE session
    ExpireSessionBobToAlice();
    ExpireSessionAliceToBob();
    err = CreateSessionBobToAlice();
    EXPECT_EQ(err, CHIP_NO_ERROR);
    err = CreateSessionAliceToBob();
    EXPECT_EQ(err, CHIP_NO_ERROR);

    Messaging::UnsolicitedMessageHandler * removedHandler = nullptr;
    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &removedHandler);
    EXPECT_EQ(err, CHIP_NO_ERROR);
    EXPECT_EQ(removedHandler, &mockReceiver);
}

#if CHIP_CONFIG_MRP_ANALYTICS_ENABLED
TEST_F(TestReliableMessageProtocol, CheckReliableMessageAnalyticsForTransmitEventualSuccessForEstablishedCase)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    // Make sure we are using CASE sessions, because there is no defunct-marking for PASE.
    ExpireSessionBobToAlice();
    ExpireSessionAliceToBob();
    err = CreateCASESessionBobToAlice();
    EXPECT_EQ(err, CHIP_NO_ERROR);
    err = CreateCASESessionAliceToBob();
    EXPECT_EQ(err, CHIP_NO_ERROR);

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);
    TestReliablityAnalyticDelegate testAnalyticsDelegate;
    rm->RegisterAnalyticsDelegate(&testAnalyticsDelegate);

    constexpr auto kTestRetryInterval = System::Clock::Milliseconds32(100_ms32);
    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        kTestRetryInterval, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        kTestRetryInterval, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    const auto expectedFabricIndex = exchange->GetSessionHandle()->GetFabricIndex();
    const auto expectedNodeId      = exchange->GetSessionHandle()->AsSecureSession()->GetPeerNodeId();

    // Let's drop the initial message
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 4;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the initial message was dropped and was added to retransmit table
    EXPECT_EQ(loopback.mNumMessagesToDrop, 3u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Wait for the first retransmission to be sent (occurs after at least 100ms but less than 1000ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
    DrainAndServiceIO();

    // Ensure the 1st retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
    DrainAndServiceIO();

    // Ensure the 2nd retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 3u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 3u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; });
    DrainAndServiceIO();

    // Ensure the 3rd retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 4u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 0u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 4u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Trigger final transmission
    GetIOContext().DriveIOUntil(1500_ms32, [&] { return loopback.mSentMessageCount >= 5; });
    DrainAndServiceIO();

    // Ensure the last retransmission was NOT dropped, and the retransmit table is empty, as we should have gotten an ack
    EXPECT_GE(loopback.mSentMessageCount, 5u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 4u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    ASSERT_EQ(testAnalyticsDelegate.mTransmitEvents.size(), 6u);
    auto firstTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(firstTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(firstTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(firstTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kInitialSend);
    EXPECT_EQ(firstTransmitEvent.retransmissionCount, std::nullopt);
    EXPECT_EQ(firstTransmitEvent.ackLatencyMs, std::nullopt);
    // We have no way of validating the first messageCounter since this is a randomly generated value, but it should
    // remain constant for all subsequent transmit events in this test.
    const uint32_t messageCounter = firstTransmitEvent.messageCounter;

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto secondTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(secondTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(secondTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(secondTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kRetransmission);
    EXPECT_EQ(secondTransmitEvent.retransmissionCount, 1);
    EXPECT_EQ(secondTransmitEvent.ackLatencyMs, std::nullopt);
    EXPECT_EQ(messageCounter, secondTransmitEvent.messageCounter);

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto thirdTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(thirdTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(thirdTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(thirdTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kRetransmission);
    EXPECT_EQ(thirdTransmitEvent.retransmissionCount, 2);
    EXPECT_EQ(thirdTransmitEvent.ackLatencyMs, std::nullopt);
    EXPECT_EQ(messageCounter, thirdTransmitEvent.messageCounter);

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto fourthTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(fourthTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(fourthTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(fourthTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kRetransmission);
    EXPECT_EQ(fourthTransmitEvent.retransmissionCount, 3);
    EXPECT_EQ(fourthTransmitEvent.ackLatencyMs, std::nullopt);
    EXPECT_EQ(messageCounter, fourthTransmitEvent.messageCounter);

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto fifthTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(fifthTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(fifthTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(fifthTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kRetransmission);
    EXPECT_EQ(fifthTransmitEvent.retransmissionCount, 4);
    EXPECT_EQ(fifthTransmitEvent.ackLatencyMs, std::nullopt);
    EXPECT_EQ(messageCounter, fifthTransmitEvent.messageCounter);

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto sixthTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(sixthTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(sixthTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(sixthTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kAcknowledged);
    EXPECT_EQ(sixthTransmitEvent.retransmissionCount, std::nullopt);
    EXPECT_TRUE(sixthTransmitEvent.ackLatencyMs.has_value());
    auto expectedMinimumAckLatencyTime = System::Clock::Milliseconds64(kTestRetryInterval * 5);
    EXPECT_GT(sixthTransmitEvent.ackLatencyMs, expectedMinimumAckLatencyTime);
    EXPECT_EQ(messageCounter, sixthTransmitEvent.messageCounter);
}

TEST_F(TestReliableMessageProtocol, CheckReliableMessageAnalyticsForTransmitFailureForEstablishedCase)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    // Make sure we are using CASE sessions, because there is no defunct-marking for PASE.
    ExpireSessionBobToAlice();
    ExpireSessionAliceToBob();
    err = CreateCASESessionBobToAlice();
    EXPECT_EQ(err, CHIP_NO_ERROR);
    err = CreateCASESessionAliceToBob();
    EXPECT_EQ(err, CHIP_NO_ERROR);

    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);
    TestReliablityAnalyticDelegate testAnalyticsDelegate;
    rm->RegisterAnalyticsDelegate(&testAnalyticsDelegate);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    const auto expectedFabricIndex = exchange->GetSessionHandle()->GetFabricIndex();
    const auto expectedNodeId      = exchange->GetSessionHandle()->AsSecureSession()->GetPeerNodeId();

    // Let's drop the initial message
    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 5;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Ensure the initial message was dropped and was added to retransmit table
    EXPECT_EQ(loopback.mNumMessagesToDrop, 4u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 1u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Wait for the initial message to fail (should take 330-413ms)
    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 2; });
    DrainAndServiceIO();

    // Ensure the 1st retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 3u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 2u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 3; });
    DrainAndServiceIO();

    // Ensure the 2nd retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 3u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 3u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    GetIOContext().DriveIOUntil(1000_ms32, [&] { return loopback.mSentMessageCount >= 4; });
    DrainAndServiceIO();

    // Ensure the 3rd retry was dropped, and is still there in the retransmit table
    EXPECT_EQ(loopback.mSentMessageCount, 4u);
    EXPECT_EQ(loopback.mNumMessagesToDrop, 1u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 4u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);

    // Trigger final transmission
    GetIOContext().DriveIOUntil(1500_ms32, [&] { return loopback.mSentMessageCount >= 5; });
    DrainAndServiceIO();

    // Ensure the last retransmission was NOT dropped, and the retransmit table is empty, as we should have gotten an ack
    EXPECT_GE(loopback.mSentMessageCount, 5u);
    EXPECT_EQ(rm->TestGetCountRetransTable(), 1);
    EXPECT_EQ(loopback.mDroppedMessageCount, 5u);

    // Now wait for our exchange to time out.
    GetIOContext().DriveIOUntil(3000_ms32, [&] { return rm->TestGetCountRetransTable() == 0; });
    DrainAndServiceIO();
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    ASSERT_EQ(testAnalyticsDelegate.mTransmitEvents.size(), 6u);
    auto firstTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(firstTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(firstTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(firstTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kInitialSend);
    EXPECT_EQ(firstTransmitEvent.retransmissionCount, std::nullopt);
    // We have no way of validating the first messageCounter since this is a randomly generated value, but it should
    // remain constant for all subsequent transmit events in this test.
    const uint32_t messageCounter = firstTransmitEvent.messageCounter;

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto secondTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(secondTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(secondTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(secondTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kRetransmission);
    EXPECT_EQ(secondTransmitEvent.retransmissionCount, 1);
    EXPECT_EQ(messageCounter, secondTransmitEvent.messageCounter);

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto thirdTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(thirdTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(thirdTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(thirdTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kRetransmission);
    EXPECT_EQ(thirdTransmitEvent.retransmissionCount, 2);
    EXPECT_EQ(messageCounter, thirdTransmitEvent.messageCounter);

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto fourthTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(fourthTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(fourthTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(fourthTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kRetransmission);
    EXPECT_EQ(fourthTransmitEvent.retransmissionCount, 3);
    EXPECT_EQ(messageCounter, fourthTransmitEvent.messageCounter);

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto fifthTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(fifthTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(fifthTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(fifthTransmitEvent.retransmissionCount, 4);
    EXPECT_EQ(fifthTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kRetransmission);
    EXPECT_EQ(messageCounter, fifthTransmitEvent.messageCounter);

    testAnalyticsDelegate.mTransmitEvents.pop();
    auto sixthTransmitEvent = testAnalyticsDelegate.mTransmitEvents.front();
    EXPECT_EQ(sixthTransmitEvent.nodeId, expectedNodeId);
    EXPECT_EQ(sixthTransmitEvent.fabricIndex, expectedFabricIndex);
    EXPECT_EQ(sixthTransmitEvent.retransmissionCount, std::nullopt);
    EXPECT_EQ(sixthTransmitEvent.eventType, ReliableMessageAnalyticsDelegate::EventType::kFailed);
    EXPECT_EQ(messageCounter, sixthTransmitEvent.messageCounter);
}

TEST_F(TestReliableMessageProtocol, CheckReliableMessageAnalyticsForTransmitEstablishedPase)
{
    CHIP_ERROR err                          = CHIP_NO_ERROR;
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    MockAppDelegate mockSender(*this);
    ExchangeContext * exchange = NewExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    TestReliablityAnalyticDelegate testAnalyticsDelegate;
    rm->RegisterAnalyticsDelegate(&testAnalyticsDelegate);

    exchange->GetSessionHandle()->AsSecureSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        100_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    ASSERT_TRUE(exchange->GetSessionHandle()->AsSecureSession()->IsPASESession());

    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Test that the message was actually sent (and not dropped)
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    ASSERT_EQ(testAnalyticsDelegate.mTransmitEvents.size(), 0u);
}

TEST_F(TestReliableMessageProtocol, CheckReliableMessageAnalyticsForTransmitUnauthenticatedExchange)
{
    chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
    EXPECT_FALSE(buffer.IsNull());

    MockSessionEstablishmentDelegate mockReceiver;
    CHIP_ERROR err = GetExchangeManager().RegisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest, &mockReceiver);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    MockSessionEstablishmentDelegate mockSender;
    ExchangeContext * exchange = NewUnauthenticatedExchangeToAlice(&mockSender);
    ASSERT_NE(exchange, nullptr);

    ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr();
    ASSERT_NE(rm, nullptr);

    TestReliablityAnalyticDelegate testAnalyticsDelegate;
    rm->RegisterAnalyticsDelegate(&testAnalyticsDelegate);

    exchange->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters(ReliableMessageProtocolConfig({
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        64_ms32, // CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL
    }));

    auto & loopback               = GetLoopback();
    loopback.mSentMessageCount    = 0;
    loopback.mNumMessagesToDrop   = 0;
    loopback.mDroppedMessageCount = 0;

    // Ensure the retransmit table is empty right now
    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer));
    EXPECT_EQ(err, CHIP_NO_ERROR);
    DrainAndServiceIO();

    // Test that the message was actually sent (and not dropped)
    EXPECT_EQ(loopback.mSentMessageCount, 2u);
    EXPECT_EQ(loopback.mDroppedMessageCount, 0u);

    EXPECT_EQ(rm->TestGetCountRetransTable(), 0);

    ASSERT_EQ(testAnalyticsDelegate.mTransmitEvents.size(), 0u);
}
#endif // CHIP_CONFIG_MRP_ANALYTICS_ENABLED

/**
 * TODO: A test that we should have but can't write with the existing
 * infrastructure we have:
 *
 * 1. A sends message 1 to B
 * 2. B is slow to respond, A does a resend and the resend is delayed in the network.
 * 3. B responds with message 2, which acks message 1.
 * 4. A sends message 3 to B
 * 5. B sends standalone ack to message 3, which is lost
 * 6. The duplicate message from step 3 is delivered and triggers a standalone ack.
 * 7. B responds with message 4, which should carry a piggyback ack for message 3
 *    (this is the part that needs testing!)
 * 8. A sends message 5 to B.
 */
