/*
 *
 *    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 <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 <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 TestReliableMessageProtocol : public chip::Test::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::Test::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;

    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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);
}

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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    // 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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    // 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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);
}

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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    // 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.
    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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);

    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);
}

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({
        30_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        30_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(3000_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({
        30_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        30_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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);
}

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({
        30_ms32, // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL
        30_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(2500_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(1000_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(500_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(1000_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);

    err = GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest);
    EXPECT_EQ(err, CHIP_NO_ERROR);
}

/**
 * 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.
 */
