/*
 *
 *    Copyright (c) 2023 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.
 */
#include <app/SubscriptionsInfoProvider.h>
#include <app/TestEventTriggerDelegate.h>
#include <app/icd/server/ICDConfigurationData.h>
#include <app/icd/server/ICDManager.h>
#include <app/icd/server/ICDMonitoringTable.h>
#include <app/icd/server/ICDNotifier.h>
#include <app/icd/server/ICDStateObserver.h>
#include <app/icd/server/tests/ICDConfigurationDataTestAccess.h>
#include <crypto/DefaultSessionKeystore.h>
#include <gtest/gtest.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/NodeId.h>
#include <lib/support/TestPersistentStorageDelegate.h>
#include <lib/support/TimeUtils.h>
#include <messaging/tests/MessagingContext.h>
#include <system/SystemLayerImpl.h>

using namespace chip;
using namespace chip::Test;
using namespace chip::app;
using namespace chip::System;
using namespace chip::System::Clock;
using namespace chip::System::Clock::Literals;

using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore;

namespace {

#if CHIP_CONFIG_ENABLE_ICD_CIP
// Test Values
constexpr uint16_t kMaxTestClients      = 2;
constexpr FabricIndex kTestFabricIndex1 = 1;
constexpr FabricIndex kTestFabricIndex2 = kMaxValidFabricIndex;
constexpr NodeId kClientNodeId11        = 0x100001;
constexpr NodeId kClientNodeId12        = 0x100002;
constexpr NodeId kClientNodeId21        = 0x200001;
constexpr NodeId kClientNodeId22        = 0x200002;

constexpr uint8_t kKeyBuffer1a[] = {
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
constexpr uint8_t kKeyBuffer1b[] = {
    0xf1, 0xe1, 0xd1, 0xc1, 0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x14, 0x31, 0x21, 0x11, 0x01
};
constexpr uint8_t kKeyBuffer2a[] = {
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f
};
constexpr uint8_t kKeyBuffer2b[] = {
    0xf2, 0xe2, 0xd2, 0xc2, 0xb2, 0xa2, 0x92, 0x82, 0x72, 0x62, 0x52, 0x42, 0x32, 0x22, 0x12, 0x02
};
#endif // CHIP_CONFIG_ENABLE_ICD_CIP

// Taken from the ICDManager Implementation
enum class ICDTestEventTriggerEvent : uint64_t
{
    kAddActiveModeReq            = 0x0046'0000'00000001,
    kRemoveActiveModeReq         = 0x0046'0000'00000002,
    kInvalidateHalfCounterValues = 0x0046'0000'00000003,
    kInvalidateAllCounterValues  = 0x0046'0000'00000004,
};

class TestICDStateObserver : public app::ICDStateObserver
{
public:
    TestICDStateObserver()  = default;
    ~TestICDStateObserver() = default;

    void OnEnterActiveMode() { mOnEnterActiveModeCalled = true; }
    void OnEnterIdleMode() { mOnEnterIdleModeCalled = true; }
    void OnTransitionToIdle() { mOnTransitionToIdleCalled = true; }
    void OnICDModeChange() { mOnICDModeChangeCalled = true; }

    void ResetOnEnterActiveMode() { mOnEnterActiveModeCalled = false; }
    void ResetOnEnterIdleMode() { mOnEnterIdleModeCalled = false; }
    void ResetOnTransitionToIdle() { mOnTransitionToIdleCalled = false; }
    void ResetOnICDModeChange() { mOnICDModeChangeCalled = false; }
    void ResetAll()
    {
        ResetOnEnterActiveMode();
        ResetOnEnterIdleMode();
        ResetOnTransitionToIdle();
        ResetOnICDModeChange();
    }

    bool mOnEnterActiveModeCalled  = false;
    bool mOnEnterIdleModeCalled    = false;
    bool mOnICDModeChangeCalled    = false;
    bool mOnTransitionToIdleCalled = false;
};

class TestSubscriptionsInfoProvider : public SubscriptionsInfoProvider
{
public:
    TestSubscriptionsInfoProvider() = default;
    ~TestSubscriptionsInfoProvider(){};

    void SetHasActiveSubscription(bool value) { mHasActiveSubscription = value; };
    void SetHasPersistedSubscription(bool value) { mHasPersistedSubscription = value; };

    bool SubjectHasActiveSubscription(FabricIndex aFabricIndex, NodeId subject) { return mHasActiveSubscription; };
    bool SubjectHasPersistedSubscription(FabricIndex aFabricIndex, NodeId subject) { return mHasPersistedSubscription; };

private:
    bool mHasActiveSubscription    = false;
    bool mHasPersistedSubscription = false;
};

System::Clock::Internal::MockClock * pMockClock          = nullptr;
System::Clock::ClockBase * pRealClock                    = nullptr;
chip::Test::LoopbackMessagingContext * pMessagingContext = nullptr;

} // namespace

namespace chip {
namespace app {

class TestICDManager : public ::testing::Test
{

public:
    /*
     * Advance the test Mock clock time by the amout passed in argument
     * and then force the SystemLayer Timer event loop. It will check for any expired timer,
     * and invoke their callbacks if there are any.
     *
     * @param time_ms: Value in milliseconds.
     */
    static void AdvanceClockAndRunEventLoop(Milliseconds64 time)
    {
        pMockClock->AdvanceMonotonic(time);
        pMessagingContext->GetIOContext().DriveIO();
    }

    // Performs shared setup for all tests in the test suite
    static void SetUpTestSuite()
    {
        if (pMockClock == nullptr)
        {
            pMockClock = new Clock::Internal::MockClock();
            ASSERT_NE(pMockClock, nullptr);
        }

        if (pMessagingContext == nullptr)
        {
            pMessagingContext = new LoopbackMessagingContext();
            ASSERT_NE(pMessagingContext, nullptr);
        }

        pMessagingContext->SetUpTestSuite();
        ASSERT_EQ(chip::DeviceLayer::PlatformMgr().InitChipStack(), CHIP_NO_ERROR);

        DeviceLayer::SetSystemLayerForTesting(&(pMessagingContext->GetSystemLayer()));
        pRealClock = &SystemClock();
        Clock::Internal::SetSystemClockForTesting(pMockClock);
    }

    // Performs shared teardown for all tests in the test suite
    static void TearDownTestSuite()
    {
        Clock::Internal::SetSystemClockForTesting(pRealClock);
        DeviceLayer::SetSystemLayerForTesting(nullptr);

        DeviceLayer::PlatformMgr().Shutdown();
        pMessagingContext->TearDownTestSuite();

        if (pMockClock != nullptr)
        {
            delete pMockClock;
            pMockClock = nullptr;
        }

        if (pMessagingContext != nullptr)
        {
            delete pMessagingContext;
            pMessagingContext = nullptr;
        }

        pRealClock = nullptr;
    }

    // Performs setup for each individual test in the test suite
    void SetUp() override
    {
        pMessagingContext->SetUp();

        mICDStateObserver.ResetAll();
        mICDManager.RegisterObserver(&mICDStateObserver);
        mICDManager.Init(&testStorage, &(pMessagingContext->GetFabricTable()), &mKeystore,
                         &(pMessagingContext->GetExchangeManager()), &mSubInfoProvider);
    }

    // Performs teardown for each individual test in the test suite
    void TearDown() override
    {
        mICDManager.Shutdown();
        pMessagingContext->TearDown();
    }

    TestSessionKeystoreImpl mKeystore;
    ICDManager mICDManager;
    TestSubscriptionsInfoProvider mSubInfoProvider;
    TestPersistentStorageDelegate testStorage;
    TestICDStateObserver mICDStateObserver;
};

TEST_F(TestICDManager, TestICDModeDurations)
{
    // After the init we should be in Idle mode
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() + 1_s);
    // Idle mode Duration expired, ICDManager transitioned to the ActiveMode.
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
    // Active mode Duration expired, ICDManager transitioned to the IdleMode.
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() + 1_s);
    // Idle mode Duration expired, ICDManager transitioned to the ActiveMode.
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Events updating the Operation to Active mode can extend the current active mode time by 1 Active mode threshold.
    // Kick an active Threshold just before the end of the ActiveMode duration and validate that the active mode is extended.
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold() / 2);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold());
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
}

#if CHIP_CONFIG_ENABLE_ICD_CIP
/**
 * @brief Test verifies that the ICDManager starts its timers correctly based on if it will have any messages to send
 *        when the IdleMode timer expires
 */
TEST_F(TestICDManager, TestICDModeDurationsWith0ActiveModeDurationWithoutActiveSub)
{
    typedef ICDListener::ICDManagementEvents ICDMEvent;
    ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();
    ICDConfigurationDataTestAccess privateIcdConfigData(&icdConfigData);

    // Set FeatureMap - Configures CIP, UAT and LITS to 1
    mICDManager.SetTestFeatureMapValue(0x07);

    // Set that there are no matching subscriptions
    mSubInfoProvider.SetHasActiveSubscription(false);
    mSubInfoProvider.SetHasPersistedSubscription(false);

    // Set New durations for test case
    Milliseconds32 oldActiveModeDuration = icdConfigData.GetActiveModeDuration();
    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);

    // Verify That ICDManager starts in Idle
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Reset IdleModeInterval since it was started before the ActiveModeDuration change
    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Force the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is now 0
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Add an entry to the ICDMonitoringTable
    ICDMonitoringTable table(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));

    ICDMonitoringEntry entry(&(mKeystore));
    entry.checkInNodeID    = kClientNodeId11;
    entry.monitoredSubject = kClientNodeId11;
    EXPECT_EQ(CHIP_NO_ERROR, entry.SetKey(ByteSpan(kKeyBuffer1a)));
    EXPECT_EQ(CHIP_NO_ERROR, table.Set(0, entry));

    // Trigger register event after first entry was added
    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is now in the LIT operating mode
    EXPECT_EQ(icdConfigData.GetICDMode(), ICDConfigurationData::ICDMode::LIT);

    // Kick an ActiveModeThreshold since a Registration can only happen from an incoming message that would transition the ICD
    // to ActiveMode
    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Expire IdleMode timer - Device should be in ActiveMode since it has an ICDM registration
    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Remove entry from the fabric - ICDManager won't have any messages to send
    EXPECT_EQ(CHIP_NO_ERROR, table.Remove(0));
    EXPECT_TRUE(table.IsEmpty());

    // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Reset Old durations
    privateIcdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
}

/**
 * @brief Test verifies that the ICDManager remains in IdleMode since it will not have any messages to send
 *        when the IdleMode timer expires
 */
TEST_F(TestICDManager, TestICDModeDurationsWith0ActiveModeDurationWithActiveSub)
{
    typedef ICDListener::ICDManagementEvents ICDMEvent;
    ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();
    ICDConfigurationDataTestAccess privateIcdConfigData(&icdConfigData);

    // Set FeatureMap - Configures CIP, UAT and LITS to 1
    mICDManager.SetTestFeatureMapValue(0x07);

    // Set that there are not matching subscriptions
    mSubInfoProvider.SetHasActiveSubscription(true);
    mSubInfoProvider.SetHasPersistedSubscription(true);

    // Set New durations for test case
    Milliseconds32 oldActiveModeDuration = icdConfigData.GetActiveModeDuration();
    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);

    // Verify That ICDManager starts in Idle
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Reset IdleModeInterval since it was started before the ActiveModeDuration change
    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Force the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is now 0
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Add an entry to the ICDMonitoringTable
    ICDMonitoringTable table(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));

    ICDMonitoringEntry entry(&(mKeystore));
    entry.checkInNodeID    = kClientNodeId11;
    entry.monitoredSubject = kClientNodeId11;
    EXPECT_EQ(CHIP_NO_ERROR, entry.SetKey(ByteSpan(kKeyBuffer1a)));
    EXPECT_EQ(CHIP_NO_ERROR, table.Set(0, entry));

    // Trigger register event after first entry was added
    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is now in the LIT operating mode
    EXPECT_EQ(icdConfigData.GetICDMode(), ICDConfigurationData::ICDMode::LIT);

    // Kick an ActiveModeThreshold since a Registration can only happen from an incoming message that would transition the ICD
    // to ActiveMode
    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Expire IdleMode timer - Device stay in IdleMode since it has an active subscription for the ICDM entry
    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Remove entry from the fabric
    EXPECT_EQ(CHIP_NO_ERROR, table.Remove(0));
    EXPECT_TRUE(table.IsEmpty());

    // Trigger unregister event after last entry was removed
    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is now in the LIT operating mode
    EXPECT_EQ(icdConfigData.GetICDMode(), ICDConfigurationData::ICDMode::SIT);

    // Kick an ActiveModeThreshold since a Unregistration can only happen from an incoming message that would transition the ICD
    // to ActiveMode
    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Return the device to return to IdleMode - Increase time by ActiveModeThreshold since ActiveModeDuration is 0
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeThreshold() + 1_ms16);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Expire Idle mode duration; ICDManager should remain in IdleMode since it has no message to send
    AdvanceClockAndRunEventLoop(icdConfigData.GetIdleModeDuration() + 1_s);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Reset Old durations
    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(oldActiveModeDuration), NullOptional);
}
#endif // CHIP_CONFIG_ENABLE_ICD_CIP

TEST_F(TestICDManager, TestKeepActivemodeRequests)
{
    typedef ICDListener::KeepActiveFlag ActiveFlag;
    ICDNotifier notifier = ICDNotifier::GetInstance();

    // Setting a requirement will transition the ICD to active mode.
    notifier.NotifyActiveRequestNotification(ActiveFlag::kCommissioningWindowOpen);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
    // Advance time so active mode duration expires.
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
    // Requirement flag still set. We stay in active mode
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Remove requirement. we should directly transition to idle mode.
    notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kCommissioningWindowOpen);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    notifier.NotifyActiveRequestNotification(ActiveFlag::kFailSafeArmed);
    // Requirement will transition us to active mode.
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Advance time, but by less than the active mode duration and remove the requirement.
    // We should stay in active mode.
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() / 2);
    notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kFailSafeArmed);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Advance time again, The activemode duration is completed.
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Set two requirements
    notifier.NotifyActiveRequestNotification(ActiveFlag::kFailSafeArmed);
    notifier.NotifyActiveRequestNotification(ActiveFlag::kExchangeContextOpen);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
    // advance time so the active mode duration expires.
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
    // A requirement flag is still set. We stay in active mode.
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // remove 1 requirement. Active mode is maintained
    notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kFailSafeArmed);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);
    // remove the last requirement
    notifier.NotifyActiveRequestWithdrawal(ActiveFlag::kExchangeContextOpen);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
}

#if CHIP_CONFIG_ENABLE_ICD_CIP
/**
 * @brief Test that verifies that the ICDManager is in the correct operating mode based on entries
 *        in the ICDMonitoringTable
 */
TEST_F(TestICDManager, TestICDMRegisterUnregisterEvents)
{
    typedef ICDListener::ICDManagementEvents ICDMEvent;
    ICDNotifier notifier = ICDNotifier::GetInstance();

    // Set FeatureMap
    // Configures CIP, UAT and LITS to 1
    mICDManager.SetTestFeatureMapValue(0x07);

    // Check ICDManager starts in SIT mode if no entries are present
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::SIT);

    // Trigger a "fake" register, ICDManager shoudl remain in SIT mode
    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager stayed in SIT mode
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::SIT);

    // Create tables with different fabrics
    ICDMonitoringTable table1(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));
    ICDMonitoringTable table2(testStorage, kTestFabricIndex2, kMaxTestClients, &(mKeystore));

    // Add first entry to the first fabric
    ICDMonitoringEntry entry1(&(mKeystore));
    entry1.checkInNodeID    = kClientNodeId11;
    entry1.monitoredSubject = kClientNodeId12;
    EXPECT_EQ(CHIP_NO_ERROR, entry1.SetKey(ByteSpan(kKeyBuffer1a)));
    EXPECT_EQ(CHIP_NO_ERROR, table1.Set(0, entry1));

    // Trigger register event after first entry was added
    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is now in the LIT operating mode
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);

    // Add second entry to the first fabric
    ICDMonitoringEntry entry2(&(mKeystore));
    entry2.checkInNodeID    = kClientNodeId12;
    entry2.monitoredSubject = kClientNodeId11;
    EXPECT_EQ(CHIP_NO_ERROR, entry2.SetKey(ByteSpan(kKeyBuffer1b)));
    EXPECT_EQ(CHIP_NO_ERROR, table1.Set(1, entry2));

    // Trigger register event after first entry was added
    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is now in the LIT operating mode
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);

    // Add first entry to the first fabric
    ICDMonitoringEntry entry3(&(mKeystore));
    entry3.checkInNodeID    = kClientNodeId21;
    entry3.monitoredSubject = kClientNodeId22;
    EXPECT_EQ(CHIP_NO_ERROR, entry3.SetKey(ByteSpan(kKeyBuffer2a)));
    EXPECT_EQ(CHIP_NO_ERROR, table2.Set(0, entry3));

    // Trigger register event after first entry was added
    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is now in the LIT operating mode
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);

    // Add second entry to the first fabric
    ICDMonitoringEntry entry4(&(mKeystore));
    entry4.checkInNodeID    = kClientNodeId22;
    entry4.monitoredSubject = kClientNodeId21;
    EXPECT_EQ(CHIP_NO_ERROR, entry4.SetKey(ByteSpan(kKeyBuffer2b)));
    EXPECT_EQ(CHIP_NO_ERROR, table2.Set(1, entry4));

    // Clear a fabric
    EXPECT_EQ(CHIP_NO_ERROR, table2.RemoveAll());

    // Trigger register event after fabric was cleared
    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is still in the LIT operating mode
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);

    // Remove single entry from remaining fabric
    EXPECT_EQ(CHIP_NO_ERROR, table1.Remove(1));

    // Trigger register event after fabric was cleared
    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is still in the LIT operating mode
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::LIT);

    // Remove last entry from remaining fabric
    EXPECT_EQ(CHIP_NO_ERROR, table1.Remove(0));
    EXPECT_TRUE(table1.IsEmpty());
    EXPECT_TRUE(table2.IsEmpty());

    // Trigger register event after fabric was cleared
    notifier.NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Check ICDManager is still in the LIT operating mode
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDMode(), ICDConfigurationData::ICDMode::SIT);
}

TEST_F(TestICDManager, TestICDCounter)
{
    uint32_t counter = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();

    // Shut down and reinit ICDManager to increment counter
    mICDManager.Shutdown();
    mICDManager.Init(&(testStorage), &(pMessagingContext->GetFabricTable()), &(mKeystore),
                     &(pMessagingContext->GetExchangeManager()), &(mSubInfoProvider));
    mICDManager.RegisterObserver(&(mICDStateObserver));

    EXPECT_EQ(counter + ICDConfigurationData::kICDCounterPersistenceIncrement,
              ICDConfigurationData::GetInstance().GetICDCounter().GetValue());
}

TEST_F(TestICDManager, TestOnSubscriptionReport)
{
    ICDNotifier notifier = ICDNotifier::GetInstance();

    // After the init we should be in Idle mode
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Trigger a subscription report
    notifier.NotifySubscriptionReport();
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Trigger another subscription report - active time should not be increased
    notifier.NotifySubscriptionReport();

    // Advance time so active mode interval expires.
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);

    // After the init we should be in Idle mode
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
}
#endif // CHIP_CONFIG_ENABLE_ICD_CIP

/**
 * @brief Test verifies the logic of the ICDManager when it receives a StayActiveRequest
 */
TEST_F(TestICDManager, TestICDMStayActive)
{
    ICDNotifier notifier                 = ICDNotifier::GetInstance();
    ICDConfigurationData & icdConfigData = ICDConfigurationData::GetInstance();

    // Verify That ICDManager starts in Idle
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Trigger a subscription report. Put the ICD manager into active mode.
    notifier.NotifySubscriptionReport();
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Advance time just before ActiveMode timer expires
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeDuration() - 1_ms32);
    // Confirm ICD manager is in active mode
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    uint32_t stayActiveRequestedMs = 20000;
    // Send a stay active request for 20 seconds
    uint32_t stayActivePromisedMs = mICDManager.StayActiveRequest(stayActiveRequestedMs);
    // confirm the promised time is the same as the requested time
    EXPECT_EQ(stayActivePromisedMs, stayActiveRequestedMs);

    // Advance time by the duration of the stay stayActiveRequestedMs - 1 ms
    AdvanceClockAndRunEventLoop(Milliseconds32(stayActiveRequestedMs) - 1_ms32);
    // Confirm ICD manager is in active mode
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Advance time by 1ms and Confirm ICD manager is in idle mode
    AdvanceClockAndRunEventLoop(1_ms32);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Trigger a subscription report Put the ICD manager into active mode
    notifier.NotifySubscriptionReport();
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Advance time by the duration of the stay active request - 1 ms
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeDuration() - 1_ms32);
    stayActiveRequestedMs = 35000;
    // Send a stay active request for 35 seconds, which is higher than the maximum stay active duration (30 seconds)
    stayActivePromisedMs = mICDManager.StayActiveRequest(stayActiveRequestedMs);
    // confirm the promised time is the maximum stay active duration (30 seconds)
    EXPECT_EQ(stayActivePromisedMs, 30000UL);

    // Advance time by the duration of the max stay active duration - 1 ms
    AdvanceClockAndRunEventLoop(Milliseconds32(30000) - 1_ms32);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Advance time by 1ms and Confirm ICD manager is in idle mode
    AdvanceClockAndRunEventLoop(1_ms32);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Trigger a subscription report Put the ICD manager into active mode
    notifier.NotifySubscriptionReport();
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Advance time by the duration of the stay active request - 1 ms
    AdvanceClockAndRunEventLoop(icdConfigData.GetActiveModeDuration() - 1_ms32);
    stayActiveRequestedMs = 30000;
    // Send a stay active request for 30 seconds
    stayActivePromisedMs = mICDManager.StayActiveRequest(stayActiveRequestedMs);
    // confirm the promised time is the same as the requested time
    EXPECT_EQ(stayActivePromisedMs, 30000UL);

    // Advance time by the duration of the stay active request - 20000 ms
    AdvanceClockAndRunEventLoop(Milliseconds32(stayActiveRequestedMs) - 20000_ms32);
    // Confirm ICD manager is in active mode, we should have 20000 seconds left at that point
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    stayActiveRequestedMs = 10000;
    stayActivePromisedMs  = mICDManager.StayActiveRequest(stayActiveRequestedMs);
    // confirm the promised time is 20000 since the device is already planing to stay active longer than the requested time
    EXPECT_EQ(stayActivePromisedMs, 20000UL);
}

#if CHIP_CONFIG_ENABLE_ICD_CIP
#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
#if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
TEST_F(TestICDManager, TestShouldCheckInMsgsBeSentAtActiveModeFunction)
{
    // Test 1 - Has no ActiveSubscription & no persisted subscription
    mSubInfoProvider.SetHasActiveSubscription(false);
    mSubInfoProvider.SetHasPersistedSubscription(false);
    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));

    // Test 2 - Has no active subscription & a persisted subscription
    mSubInfoProvider.SetHasActiveSubscription(false);
    mSubInfoProvider.SetHasPersistedSubscription(true);
    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));

    // Test 3 - Has an active subscription & a persisted subscription
    mSubInfoProvider.SetHasActiveSubscription(true);
    mSubInfoProvider.SetHasPersistedSubscription(true);
    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
}
#else
TEST_F(TestICDManager, TestShouldCheckInMsgsBeSentAtActiveModeFunction)
{
    // Test 1 - Has no active subscription and no persisted subscription at boot up
    mSubInfoProvider.SetHasActiveSubscription(false);
    mSubInfoProvider.SetHasPersistedSubscription(false);
    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));

    // Test 2 - Has no active subscription and a persisted subscription at boot up
    mSubInfoProvider.SetHasActiveSubscription(false);
    mSubInfoProvider.SetHasPersistedSubscription(true);
    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));

    mICDManager.SetBootUpResumeSubscriptionExecuted();

    // Test 3 - Has an active subscription and a persisted subscription during normal operations
    mSubInfoProvider.SetHasActiveSubscription(true);
    mSubInfoProvider.SetHasPersistedSubscription(true);
    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));

    // Test 4 - Has no active subscription and a persisted subscription during normal operations
    mSubInfoProvider.SetHasActiveSubscription(false);
    mSubInfoProvider.SetHasPersistedSubscription(true);
    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
}
#endif // CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
#else
TEST_F(TestICDManager, TestShouldCheckInMsgsBeSentAtActiveModeFunction)
{
    // Test 1 - Has an active subscription
    mSubInfoProvider.SetHasActiveSubscription(true);
    EXPECT_FALSE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));

    // Test 2 - Has no active subscription
    mSubInfoProvider.SetHasActiveSubscription(false);
    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));

    // Test 3 - Make sure that the persisted subscription has no impact
    mSubInfoProvider.SetHasPersistedSubscription(true);
    EXPECT_TRUE(mICDManager.ShouldCheckInMsgsBeSentAtActiveModeFunction(kTestFabricIndex1, kClientNodeId11));
}
#endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
#endif // CHIP_CONFIG_ENABLE_ICD_CIP

TEST_F(TestICDManager, TestHandleTestEventTriggerActiveModeReq)
{
    // Verify That ICDManager starts in Idle
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);

    // Add ActiveMode req for the Test event trigger event
    mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kAddActiveModeReq));
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Advance clock by the ActiveModeDuration and check that the device is still in ActiveMode
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() + 1_ms32);
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::ActiveMode);

    // Remove req and device should go to IdleMode
    mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kRemoveActiveModeReq));
    EXPECT_EQ(mICDManager.GetOperaionalState(), ICDManager::OperationalState::IdleMode);
}

#if CHIP_CONFIG_ENABLE_ICD_CIP
TEST_F(TestICDManager, TestHandleTestEventTriggerInvalidateHalfCounterValues)
{
    constexpr uint32_t startValue    = 1;
    constexpr uint32_t expectedValue = 2147483648;

    // Set starting value
    uint32_t currentValue = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();
    uint32_t delta        = startValue - currentValue;

    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().AdvanceBy(delta), CHIP_NO_ERROR);
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().GetValue(), startValue);

    // Trigger ICD kInvalidateHalfCounterValues event
    mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kInvalidateHalfCounterValues));

    // Validate counter has the expected value
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().GetValue(), expectedValue);
}

TEST_F(TestICDManager, TestHandleTestEventTriggerInvalidateAllCounterValues)
{
    constexpr uint32_t startValue    = 105;
    constexpr uint32_t expectedValue = 104;

    // Set starting value
    uint32_t currentValue = ICDConfigurationData::GetInstance().GetICDCounter().GetValue();
    uint32_t delta        = startValue - currentValue;

    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().AdvanceBy(delta), CHIP_NO_ERROR);
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().GetValue(), startValue);

    // Trigger ICD kInvalidateAllCounterValues event
    mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kInvalidateAllCounterValues));

    // Validate counter has the expected value
    EXPECT_EQ(ICDConfigurationData::GetInstance().GetICDCounter().GetValue(), expectedValue);
}
#endif // CHIP_CONFIG_ENABLE_ICD_CIP

/**
 * @brief Test verifies when OnEnterIdleMode is called during normal operations.
 *        Without the ActiveMode timer being extended
 */
TEST_F(TestICDManager, TestICDStateObserverOnEnterIdleModeActiveModeDuration)
{
    // Verify that ICDManager starts in IdleMode and calls OnEnterIdleMode
    EXPECT_TRUE(mICDStateObserver.mOnEnterIdleModeCalled);
    mICDStateObserver.ResetOnEnterIdleMode();

    // Advance clock just before IdleMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);

    // Expire IdleModeInterval
    AdvanceClockAndRunEventLoop(1_s);
    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);

    // Advance clock Just before ActiveMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);

    // Expire ActiveMode timer
    AdvanceClockAndRunEventLoop(1_ms32);
    EXPECT_TRUE(mICDStateObserver.mOnEnterIdleModeCalled);
}

/**
 * @brief Test verifies when OnEnterIdleMode is called with the ActiveMode timer gets extended
 */
TEST_F(TestICDManager, TestICDStateObserverOnEnterIdleModeActiveModeThreshold)
{
    // Verify that ICDManager starts in IdleMode and calls OnEnterIdleMode
    EXPECT_TRUE(mICDStateObserver.mOnEnterIdleModeCalled);
    mICDStateObserver.ResetOnEnterIdleMode();

    // Advance clock just before the IdleMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);

    // Expire IdleMode timer
    AdvanceClockAndRunEventLoop(1_s);
    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);

    // Advance clock Just before ActiveMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);
    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);

    // Increase ActiveMode timer by one ActiveModeThreshold
    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);

    // Advance clock Just before ActiveMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold() - 1_ms32);
    EXPECT_FALSE(mICDStateObserver.mOnEnterIdleModeCalled);

    // Expire ActiveMode timer
    AdvanceClockAndRunEventLoop(1_ms32);
    EXPECT_TRUE(mICDStateObserver.mOnEnterIdleModeCalled);
}

TEST_F(TestICDManager, TestICDStateObserverOnEnterActiveMode)
{
    // Verify OnEnterActiveMode wasn't called at Init
    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);

    // Advance clock just before IdleMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);

    // Expire IdleMode timer and check wether OnEnterActiveMode was called
    AdvanceClockAndRunEventLoop(1_s);
    EXPECT_TRUE(mICDStateObserver.mOnEnterActiveModeCalled);
    mICDStateObserver.ResetOnEnterActiveMode();

    // Advance clock just before the ActiveMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() - 1_ms32);

    // Verify OnEnterActiveMde wasn't called
    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);

    // Increase ActiveMode timer by one ActiveModeThreshold
    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();

    // Verify OnEnterActiveMde wasn't called
    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);

    // Advance clock just before ActiveMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold() - 1_ms32);

    // Verify OnEnterActiveMde wasn't called
    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);

    // Expire ActiveMode timer
    AdvanceClockAndRunEventLoop(1_ms32);

    // Verify OnEnterActiveMde wasn't called
    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);

    // Advance clock just before IdleMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
    EXPECT_FALSE(mICDStateObserver.mOnEnterActiveModeCalled);

    // Expire IdleMode timer and check OnEnterActiveMode was called
    AdvanceClockAndRunEventLoop(1_s);
    EXPECT_TRUE(mICDStateObserver.mOnEnterActiveModeCalled);
}

#if CHIP_CONFIG_ENABLE_ICD_CIP
TEST_F(TestICDManager, TestICDStateObserverOnICDModeChange)
{
    typedef ICDListener::ICDManagementEvents ICDMEvent;

    // Set FeatureMap - Configures CIP, UAT and LITS to 1
    mICDManager.SetTestFeatureMapValue(0x07);

    // Since we don't have a registration, we stay in SIT mode. No changes
    EXPECT_FALSE(mICDStateObserver.mOnICDModeChangeCalled);

    // Trigger register event to force ICDManager to re-evaluate OperatingMode
    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Since we don't have a registration, we stay in SIT mode. No changes
    EXPECT_FALSE(mICDStateObserver.mOnICDModeChangeCalled);

    // Add an entry to the ICDMonitoringTable
    ICDMonitoringTable table(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));

    ICDMonitoringEntry entry(&(mKeystore));
    entry.checkInNodeID    = kClientNodeId11;
    entry.monitoredSubject = kClientNodeId11;
    EXPECT_EQ(CHIP_NO_ERROR, entry.SetKey(ByteSpan(kKeyBuffer1a)));
    EXPECT_EQ(CHIP_NO_ERROR, table.Set(0, entry));

    // Trigger register event after first entry was added
    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // We have a registration. Transition to LIT mode
    EXPECT_TRUE(mICDStateObserver.mOnICDModeChangeCalled);
    mICDStateObserver.ResetOnICDModeChange();

    // Trigger register event to force ICDManager to re-evaluate OperatingMode
    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // We have a registration. We stay in LIT mode. No changes.
    EXPECT_FALSE(mICDStateObserver.mOnICDModeChangeCalled);

    // Remove entry from the ICDMonitoringTable
    EXPECT_EQ(CHIP_NO_ERROR, table.Remove(0));
    ICDNotifier::GetInstance().NotifyICDManagementEvent(ICDMEvent::kTableUpdated);

    // Since we don't have a registration anymore. Transition to SIT mode.
    EXPECT_TRUE(mICDStateObserver.mOnICDModeChangeCalled);
    mICDStateObserver.ResetOnICDModeChange();
}

TEST_F(TestICDManager, TestICDStateObserverOnICDModeChangeOnInit)
{
    // Set FeatureMap - Configures CIP, UAT and LITS to 1
    mICDManager.SetTestFeatureMapValue(0x07);

    ICDMonitoringTable table(testStorage, kTestFabricIndex1, kMaxTestClients, &(mKeystore));

    // Since we don't have a registration, we stay in SIT mode. No changes
    EXPECT_FALSE(mICDStateObserver.mOnICDModeChangeCalled);

    // Add an entry to the ICDMonitoringTable
    ICDMonitoringEntry entry(&(mKeystore));
    entry.checkInNodeID    = kClientNodeId11;
    entry.monitoredSubject = kClientNodeId11;
    EXPECT_EQ(CHIP_NO_ERROR, entry.SetKey(ByteSpan(kKeyBuffer1a)));
    EXPECT_EQ(CHIP_NO_ERROR, table.Set(0, entry));

    // Shut down and reinit ICDManager - We should go to LIT mode since we have a registration
    mICDManager.Shutdown();
    mICDManager.RegisterObserver(&(mICDStateObserver));
    mICDManager.Init(&testStorage, &(pMessagingContext->GetFabricTable()), &mKeystore, &(pMessagingContext->GetExchangeManager()),
                     &mSubInfoProvider);

    // We have a registration, transition to LIT mode
    EXPECT_TRUE(mICDStateObserver.mOnICDModeChangeCalled);
    mICDStateObserver.ResetOnICDModeChange();

    // Remove entry from the ICDMonitoringTable
    EXPECT_EQ(CHIP_NO_ERROR, table.Remove(0));
}
#endif

/**
 * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is greater than the
 *        ICD_ACTIVE_TIME_JITTER_MS
 */
TEST_F(TestICDManager, TestICDStateObserverOnTransitionToIdleModeGreaterActiveModeDuration)
{
    ICDConfigurationDataTestAccess privateIcdConfigData(&ICDConfigurationData::GetInstance());

    // Set New durations for test case - ActiveModeDuration must be longuer than ICD_ACTIVE_TIME_JITTER_MS
    Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
    privateIcdConfigData.SetModeDurations(
        MakeOptional<Milliseconds32>(Milliseconds32(200) + Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS)), NullOptional);

    // Advance clock just before IdleMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Expire IdleMode timer
    AdvanceClockAndRunEventLoop(1_s);
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Advance time just before OnTransitionToIdleMode is called
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeDuration() -
                                Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS) - 1_ms32);

    // Check mOnTransitionToIdleCalled has not been called
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Increase ActiveMode timer by one ActiveModeThreshold
    ICDNotifier::GetInstance().NotifyNetworkActivityNotification();
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Advance time just before OnTransitionToIdleMode is called
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold() -
                                Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS) - 1_ms32);
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Expire OnTransitionToIdleMode
    AdvanceClockAndRunEventLoop(1_ms32);
    // Check mOnTransitionToIdleCalled has been called
    EXPECT_TRUE(mICDStateObserver.mOnTransitionToIdleCalled);
    mICDStateObserver.ResetOnTransitionToIdle();

    // Expire ActiveMode timer
    AdvanceClockAndRunEventLoop(Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS));
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Reset Old durations
    privateIcdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
}

/**
 * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is equal to the
 *        ICD_ACTIVE_TIME_JITTER_MS.
 */
TEST_F(TestICDManager, TestICDStateObserverOnTransitionToIdleModeEqualActiveModeDuration)
{
    ICDConfigurationDataTestAccess privateIcdConfigData(&ICDConfigurationData::GetInstance());

    // Set New durations for test case - ActiveModeDuration must be equal to ICD_ACTIVE_TIME_JITTER_MS
    Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(Milliseconds32(ICD_ACTIVE_TIME_JITTER_MS)), NullOptional);

    // Advance clock just before IdleMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Expire IdleMode timer
    AdvanceClockAndRunEventLoop(1_s);
    // In this scenario, The ICD state machine kicked a OnTransitionToIdle timer with a duration of 0 seconds.
    // The freeRTOS systemlayer timer calls a 0s timer's callback instantly while on posix it take and 1 addition event loop.
    // Thefore, the expect result diverges here based on the systemlayer implementation. Skip this check.
    // https://github.com/project-chip/connectedhomeip/issues/33441
    // EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Expire OnTransitionToIdleMode
    AdvanceClockAndRunEventLoop(1_ms32);
    // All systems should have called the OnTransitionToIdle callback by now.
    EXPECT_TRUE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Reset Old durations
    privateIcdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
}

/**
 * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is 0 and without an ActiveMode req
 */
TEST_F(TestICDManager, TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWithoutReq)
{
    ICDConfigurationDataTestAccess privateIcdConfigData(&ICDConfigurationData::GetInstance());

    // Set New durations for test case - ActiveModeDuration equal 0
    Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
    privateIcdConfigData.SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);

    // Advance clock just before IdleMode timer expires
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration() - 1_s);
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Expire IdleMode timer
    AdvanceClockAndRunEventLoop(1_s);
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Increase time by 1 - Should not trigger OnTransitionToIdle.
    // Timer length is one ActiveModeThreshold
    AdvanceClockAndRunEventLoop(1_ms32);
    EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Expire ActiveModeThreshold
    AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetActiveModeThreshold());
    EXPECT_TRUE(mICDStateObserver.mOnTransitionToIdleCalled);

    // Reset Old durations
    privateIcdConfigData.SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
}

/**
 * @brief Test verifies the OnTransitionToIdleMode event when the ActiveModeDuration is 0 with an ActiveMode req
 *        TODO(#33074): When the OnTransitionToIdle edge is fixed, we can enable this test
 */
// TEST_F(TestICDManager, TestICDStateObserverOnTransitionToIdleMode0ActiveModeDurationWithReq)
// {
//     // Set New durations for test case - ActiveModeDuration equal 0
//     Milliseconds32 oldActiveModeDuration = ICDConfigurationData::GetInstance().GetActiveModeDuration();
//     ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional<Milliseconds32>(0), NullOptional);

//     // Add ActiveMode req for the Test event trigger event
//     mICDManager.HandleEventTrigger(static_cast<uint64_t>(ICDTestEventTriggerEvent::kAddActiveModeReq));

//     // Expire IdleMode timer
//     AdvanceClockAndRunEventLoop(ICDConfigurationData::GetInstance().GetIdleModeDuration());
//     EXPECT_FALSE(mICDStateObserver.mOnTransitionToIdleCalled);

//     // Reset Old durations
//     ICDConfigurationData::GetInstance().SetModeDurations(MakeOptional(oldActiveModeDuration), NullOptional);
// }

} // namespace app
} // namespace chip
