/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include <app/AppConfig.h>
#include <app/InteractionModelEngine.h>
#include <app/icd/server/ICDServerConfig.h>
#include <app/reporting/tests/MockReportScheduler.h>
#include <app/tests/AppTestContext.h>
#include <app/util/mock/Constants.h>
#include <app/util/mock/Functions.h>
#include <data-model-providers/codegen/Instance.h>
#include <lib/core/CASEAuthTag.h>
#include <lib/core/ErrorStr.h>
#include <lib/core/StringBuilderAdapters.h>
#include <lib/core/TLV.h>
#include <lib/core/TLVDebug.h>
#include <lib/core/TLVUtilities.h>
#include <lib/support/tests/ExtraPwTestMacros.h>
#include <messaging/ExchangeContext.h>
#include <messaging/Flags.h>
#include <platform/CHIPDeviceLayer.h>
#include <pw_unit_test/framework.h>

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
#include <app/SimpleSubscriptionResumptionStorage.h>
#include <lib/support/TestPersistentStorageDelegate.h>
#endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS

namespace {

class NullReadHandlerCallback : public chip::app::ReadHandler::ManagementCallback
{
public:
    void OnDone(chip::app::ReadHandler & apReadHandlerObj) override {}
    chip::app::ReadHandler::ApplicationCallback * GetAppCallback() override { return nullptr; }
    chip::app::InteractionModelEngine * GetInteractionModelEngine() override
    {
        return chip::app::InteractionModelEngine::GetInstance();
    }
};

} // namespace

namespace chip {
namespace app {
class TestInteractionModelEngine : public chip::Testing::AppContext
{
public:
    void TestSubjectHasActiveSubscriptionSingleSubOneEntry();
    void TestSubjectHasActiveSubscriptionSingleSubMultipleEntries();
    void TestSubjectHasActiveSubscriptionMultipleSubsSingleEntry();
    void TestSubjectHasActiveSubscriptionMultipleSubsMultipleEntries();
    void TestSubjectHasActiveSubscriptionSubWithCAT();
    void TestSubscriptionResumptionTimer();
    void TestDecrementNumSubscriptionsToResume();
    void TestFabricHasAtLeastOneActiveSubscription();
    void TestFabricHasAtLeastOneActiveSubscriptionWithMixedStates();
    static int GetAttributePathListLength(SingleLinkedListNode<AttributePathParams> * apattributePathParamsList);
};

int TestInteractionModelEngine::GetAttributePathListLength(SingleLinkedListNode<AttributePathParams> * apAttributePathParamsList)
{
    int length                                         = 0;
    SingleLinkedListNode<AttributePathParams> * runner = apAttributePathParamsList;
    while (runner != nullptr)
    {
        runner = runner->mpNext;
        length++;
    }
    return length;
}

TEST_F(TestInteractionModelEngine, TestAttributePathParamsPushRelease)
{

    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR);

    SingleLinkedListNode<AttributePathParams> * attributePathParamsList = nullptr;
    AttributePathParams attributePathParams1;
    AttributePathParams attributePathParams2;
    AttributePathParams attributePathParams3;

    attributePathParams1.mEndpointId = 1;
    attributePathParams2.mEndpointId = 2;
    attributePathParams3.mEndpointId = 3;

    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1));

    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2));
    ASSERT_NE(attributePathParamsList, nullptr);
    EXPECT_EQ(attributePathParams2.mEndpointId, attributePathParamsList->mValue.mEndpointId);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 2);

    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams3));
    ASSERT_NE(attributePathParamsList, nullptr);
    EXPECT_EQ(attributePathParams3.mEndpointId, attributePathParamsList->mValue.mEndpointId);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 3);

    engine->ReleaseAttributePathList(attributePathParamsList);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 0);
}

TEST_F(TestInteractionModelEngine, TestRemoveDuplicateConcreteAttribute)
{

    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()));

    SingleLinkedListNode<AttributePathParams> * attributePathParamsList = nullptr;
    AttributePathParams attributePathParams1;
    AttributePathParams attributePathParams2;
    AttributePathParams attributePathParams3;

    // Three concrete paths, no duplicates
    attributePathParams1.mEndpointId  = chip::Testing::kMockEndpoint3;
    attributePathParams1.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams1.mAttributeId = chip::Testing::MockAttributeId(1);

    attributePathParams2.mEndpointId  = chip::Testing::kMockEndpoint3;
    attributePathParams2.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams2.mAttributeId = chip::Testing::MockAttributeId(2);

    attributePathParams3.mEndpointId  = chip::Testing::kMockEndpoint3;
    attributePathParams3.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams3.mAttributeId = chip::Testing::MockAttributeId(3);

    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams3));
    engine->RemoveDuplicateConcreteAttributePath(attributePathParamsList);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 3);
    engine->ReleaseAttributePathList(attributePathParamsList);

    attributePathParams1.mEndpointId  = kInvalidEndpointId;
    attributePathParams1.mClusterId   = kInvalidClusterId;
    attributePathParams1.mAttributeId = kInvalidAttributeId;

    attributePathParams2.mEndpointId  = chip::Testing::kMockEndpoint3;
    attributePathParams2.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams2.mAttributeId = chip::Testing::MockAttributeId(2);

    attributePathParams3.mEndpointId  = chip::Testing::kMockEndpoint3;
    attributePathParams3.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams3.mAttributeId = chip::Testing::MockAttributeId(3);

    // 1st path is wildcard endpoint, 2nd, 3rd paths are concrete paths, the concrete ones would be removed.
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams3));
    engine->RemoveDuplicateConcreteAttributePath(attributePathParamsList);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 1);
    engine->ReleaseAttributePathList(attributePathParamsList);

    // 2nd path is wildcard endpoint, 1st, 3rd paths are concrete paths, the latter two would be removed.
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams3));
    engine->RemoveDuplicateConcreteAttributePath(attributePathParamsList);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 1);
    engine->ReleaseAttributePathList(attributePathParamsList);

    // 3nd path is wildcard endpoint, 1st, 2nd paths are concrete paths, the latter two would be removed.
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams3));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1));
    engine->RemoveDuplicateConcreteAttributePath(attributePathParamsList);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 1);
    engine->ReleaseAttributePathList(attributePathParamsList);

    attributePathParams1.mEndpointId  = chip::Testing::kMockEndpoint3;
    attributePathParams1.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams1.mAttributeId = kInvalidAttributeId;

    attributePathParams2.mEndpointId  = chip::Testing::kMockEndpoint2;
    attributePathParams2.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams2.mAttributeId = chip::Testing::MockAttributeId(2);

    attributePathParams3.mEndpointId  = chip::Testing::kMockEndpoint2;
    attributePathParams3.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams3.mAttributeId = chip::Testing::MockAttributeId(3);

    // 1st is wildcard one, but not intersect with the latter two concrete paths, so the paths in total are 3 finally
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams3));
    engine->RemoveDuplicateConcreteAttributePath(attributePathParamsList);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 3);
    engine->ReleaseAttributePathList(attributePathParamsList);

    attributePathParams1.mEndpointId  = kInvalidEndpointId;
    attributePathParams1.mClusterId   = kInvalidClusterId;
    attributePathParams1.mAttributeId = kInvalidAttributeId;

    attributePathParams2.mEndpointId  = chip::Testing::kMockEndpoint3;
    attributePathParams2.mClusterId   = kInvalidClusterId;
    attributePathParams2.mAttributeId = kInvalidAttributeId;

    attributePathParams3.mEndpointId  = kInvalidEndpointId;
    attributePathParams3.mClusterId   = kInvalidClusterId;
    attributePathParams3.mAttributeId = chip::Testing::MockAttributeId(3);

    // Wildcards cannot be deduplicated.
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams3));
    engine->RemoveDuplicateConcreteAttributePath(attributePathParamsList);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 3);
    engine->ReleaseAttributePathList(attributePathParamsList);

    attributePathParams1.mEndpointId  = kInvalidEndpointId;
    attributePathParams1.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams1.mAttributeId = chip::Testing::MockAttributeId(10);

    attributePathParams2.mEndpointId  = chip::Testing::kMockEndpoint3;
    attributePathParams2.mClusterId   = chip::Testing::MockClusterId(2);
    attributePathParams2.mAttributeId = chip::Testing::MockAttributeId(10);

    // 1st path is wildcard endpoint, 2nd path is invalid attribute
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1));
    EXPECT_SUCCESS(engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2));
    engine->RemoveDuplicateConcreteAttributePath(attributePathParamsList);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 2);
    engine->ReleaseAttributePathList(attributePathParamsList);
}

/**
 * @brief Test verifies the SubjectHasActiveSubscription with a single subscription with a single entry
 */
TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscriptionSingleSubOneEntry)
{

    NullReadHandlerCallback nullCallback;
    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    NodeId bobNodeId           = 0x12344321ull;
    FabricIndex bobFabricIndex = 1;

    // Create ExchangeContext
    Messaging::ExchangeContext * exchangeCtx1 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx1);

    // InteractionModelEngine init
    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler()));

    // Verify that there are no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Create and setup readHandler 1
    ReadHandler * readHandler1 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx1, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Verify that Bob still doesn't have an active subscription
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Set readHandler1 to active
    readHandler1->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that Bob still has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Clean up read handlers
    engine->GetReadHandlerPool().ReleaseAll();

    // Verify that there are no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));
}

/**
 * @brief Test verifies that the SubjectHasActiveSubscription will continue iterating till it fines at least one valid active
 * subscription
 */
TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscriptionSingleSubMultipleEntries)
{

    NullReadHandlerCallback nullCallback;
    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    NodeId bobNodeId           = 0x12344321ull;
    FabricIndex bobFabricIndex = 1;

    // Create ExchangeContexts
    Messaging::ExchangeContext * exchangeCtx1 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx1);

    Messaging::ExchangeContext * exchangeCtx2 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx1);

    // InteractionModelEngine init
    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler()));

    // Verify that both Alice and Bob have no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Create readHandler 1
    engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx1, ReadHandler::InteractionType::Subscribe,
                                              reporting::GetDefaultReportScheduler());

    // Verify that Bob still doesn't have an active subscription
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Create and setup readHandler 2
    ReadHandler * readHandler2 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx2, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Verify that Bob still doesn't have an active subscription
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Set readHandler2 to active
    readHandler2->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that Bob has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Release active ReadHandler
    engine->GetReadHandlerPool().ReleaseObject(readHandler2);

    // Verify that there are no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Clean up read handlers
    engine->GetReadHandlerPool().ReleaseAll();
}

/**
 * @brief Test validates that the SubjectHasActiveSubscription can support multiple subscriptions from different clients
 */
TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscriptionMultipleSubsSingleEntry)
{

    NullReadHandlerCallback nullCallback;
    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    NodeId bobNodeId             = 0x12344321ull;
    FabricIndex bobFabricIndex   = 1;
    NodeId aliceNodeId           = 0x11223344ull;
    FabricIndex aliceFabricIndex = 2;

    // Create ExchangeContexts
    Messaging::ExchangeContext * exchangeCtx1 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx1);

    Messaging::ExchangeContext * exchangeCtx2 = NewExchangeToAlice(nullptr, false);
    ASSERT_TRUE(exchangeCtx2);

    // InteractionModelEngine init
    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler()));

    // Verify that both Alice and Bob have no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Create and setup readHandler 1
    ReadHandler * readHandler1 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx1, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Create and setup readHandler 2
    ReadHandler * readHandler2 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx2, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Verify that Bob still doesn't have an active subscription
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Set readHandler1 to active
    readHandler1->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that Bob has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Verify that Alice still doesn't have an active subscription
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Set readHandler2 to active
    readHandler2->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that Bob has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Verify that Alice has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Set readHandler1 to inactive
    readHandler1->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, false);

    // Verify that Bob doesn't have an active subscription
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Verify that Alice still has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Clean up read handlers
    engine->GetReadHandlerPool().ReleaseAll();

    // Verify that both Alice and Bob have no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));
}

/**
 * @brief Test validates that the SubjectHasActiveSubscription can find the active subscription even if there are multiple
 * subscriptions for each client
 */
TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscriptionMultipleSubsMultipleEntries)
{
    NullReadHandlerCallback nullCallback;
    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    NodeId bobNodeId             = 0x12344321ull;
    FabricIndex bobFabricIndex   = 1;
    NodeId aliceNodeId           = 0x11223344ull;
    FabricIndex aliceFabricIndex = 2;

    // Create ExchangeContexts
    Messaging::ExchangeContext * exchangeCtx11 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx11);

    Messaging::ExchangeContext * exchangeCtx12 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx12);

    Messaging::ExchangeContext * exchangeCtx21 = NewExchangeToAlice(nullptr, false);
    ASSERT_TRUE(exchangeCtx21);

    Messaging::ExchangeContext * exchangeCtx22 = NewExchangeToAlice(nullptr, false);
    ASSERT_TRUE(exchangeCtx22);

    // InteractionModelEngine init
    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler()));

    // Verify that both Alice and Bob have no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Create and setup readHandler 1-1
    engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx11, ReadHandler::InteractionType::Subscribe,
                                              reporting::GetDefaultReportScheduler());

    // Create and setup readHandler 1-2
    ReadHandler * readHandler12 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx12, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Create and setup readHandler 2-1
    engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx21, ReadHandler::InteractionType::Subscribe,
                                              reporting::GetDefaultReportScheduler());

    // Create and setup readHandler 2-2
    ReadHandler * readHandler22 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx22, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Verify that both Alice and Bob have no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Set readHandler 1-2 to active
    readHandler12->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that Bob has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Verify that Alice still doesn't have an active subscription
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Set readHandler 2-2 to active
    readHandler22->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that Bob has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Verify that Alice has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Set readHandler1 to inactive
    readHandler12->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, false);

    // Verify that Bob doesn't have an active subscription
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));

    // Verify that Alice still has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));

    // Clean up read handlers
    engine->GetReadHandlerPool().ReleaseAll();

    // Verify that both Alice and Bob have no active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId));
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(aliceFabricIndex, aliceNodeId));
}

/**
 * @brief Verifies that SubjectHasActiveSubscription support CATs as a subject-id
 */
TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscriptionSubWithCAT)
{
    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();
    NullReadHandlerCallback nullCallback;

    CASEAuthTag cat            = 0x1111'0001;
    CASEAuthTag invalidCAT     = 0x1112'0001;
    CATValues cats             = CATValues{ { cat } };
    NodeId valideSubjectId     = NodeIdFromCASEAuthTag(cat);
    NodeId invalideSubjectId   = NodeIdFromCASEAuthTag(invalidCAT);
    FabricIndex bobFabricIndex = 1;

    // InteractionModelEngine init
    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler()));

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

    // Create ExchangeContexts
    Messaging::ExchangeContext * exchangeCtx = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx);

    // Create readHandler
    ReadHandler * readHandler = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Verify there are not active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, valideSubjectId));
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, invalideSubjectId));

    // Set readHandler to active
    readHandler->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify tthat valid subjectID has an active subscription
    EXPECT_TRUE(engine->SubjectHasActiveSubscription(bobFabricIndex, valideSubjectId));
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, invalideSubjectId));

    // Clean up read handlers
    engine->GetReadHandlerPool().ReleaseAll();

    // Verify there are not active subscriptions
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, valideSubjectId));
    EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, invalideSubjectId));
}

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS

/**
 * @brief Test verifies the SubjectHasPersistedSubscription with single and multiple persisted subscriptions.
 */
TEST_F(TestInteractionModelEngine, TestSubjectHasPersistedSubscription)
{
    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    chip::TestPersistentStorageDelegate storage;
    chip::app::SimpleSubscriptionResumptionStorage subscriptionStorage;

    EXPECT_EQ(subscriptionStorage.Init(&storage), CHIP_NO_ERROR);

    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(CHIP_NO_ERROR,
              engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler(), nullptr,
                           &subscriptionStorage));

    NodeId nodeId1      = 1;
    FabricIndex fabric1 = 1;
    SubscriptionId sub1 = 1;
    NodeId nodeId2      = 2;
    FabricIndex fabric2 = 2;
    SubscriptionId sub2 = 2;

    SubscriptionResumptionStorage::SubscriptionInfo info1 = { .mNodeId         = nodeId1,
                                                              .mFabricIndex    = fabric1,
                                                              .mSubscriptionId = sub1 };
    SubscriptionResumptionStorage::SubscriptionInfo info2 = { .mNodeId         = nodeId2,
                                                              .mFabricIndex    = fabric2,
                                                              .mSubscriptionId = sub2 };

    // Test with no persisted subscriptions - Should return false
    EXPECT_FALSE(engine->SubjectHasPersistedSubscription(fabric1, nodeId1));

    // Add one entry
    EXPECT_EQ(CHIP_NO_ERROR, subscriptionStorage.Save(info1));

    // Verify that entry matches - Should return true
    EXPECT_TRUE(engine->SubjectHasPersistedSubscription(fabric1, nodeId1));

    // Test with absent subscription - Should return false
    EXPECT_FALSE(engine->SubjectHasPersistedSubscription(fabric2, nodeId2));

    // Add second entry
    EXPECT_EQ(CHIP_NO_ERROR, subscriptionStorage.Save(info2));

    // Verify that entry matches - Should return true
    EXPECT_TRUE(engine->SubjectHasPersistedSubscription(fabric2, nodeId2));
    EXPECT_TRUE(engine->SubjectHasPersistedSubscription(fabric1, nodeId1));

    // Remove an entry
    EXPECT_EQ(CHIP_NO_ERROR, subscriptionStorage.Delete(nodeId1, fabric1, sub1));

    // Test with absent subscription - Should return false
    EXPECT_FALSE(engine->SubjectHasPersistedSubscription(fabric1, nodeId1));

    // Clean Up entries
    EXPECT_SUCCESS(subscriptionStorage.DeleteAll(fabric1));
    EXPECT_SUCCESS(subscriptionStorage.DeleteAll(fabric2));
}

#if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION

TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubscriptionResumptionTimer)
{

    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR);

    uint32_t timeTillNextResubscriptionMs;
    engine->mNumSubscriptionResumptionRetries = 0;
    timeTillNextResubscriptionMs              = engine->ComputeTimeSecondsTillNextSubscriptionResumption();
    EXPECT_EQ(timeTillNextResubscriptionMs, (unsigned) CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION_MIN_RETRY_INTERVAL_SECS);

    uint32_t lastTimeTillNextResubscriptionMs = timeTillNextResubscriptionMs;
    for (engine->mNumSubscriptionResumptionRetries = 1;
         engine->mNumSubscriptionResumptionRetries <= CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION_MAX_FIBONACCI_STEP_INDEX;
         engine->mNumSubscriptionResumptionRetries++)
    {
        timeTillNextResubscriptionMs = engine->ComputeTimeSecondsTillNextSubscriptionResumption();
        EXPECT_GE(timeTillNextResubscriptionMs, lastTimeTillNextResubscriptionMs);
        EXPECT_LT(timeTillNextResubscriptionMs, (unsigned) CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION_MAX_RETRY_INTERVAL_SECS);
        lastTimeTillNextResubscriptionMs = timeTillNextResubscriptionMs;
    }

    engine->mNumSubscriptionResumptionRetries = 2000;
    timeTillNextResubscriptionMs              = engine->ComputeTimeSecondsTillNextSubscriptionResumption();
    EXPECT_EQ(timeTillNextResubscriptionMs, (unsigned) CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION_MAX_RETRY_INTERVAL_SECS);
}

#endif // CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION

TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestDecrementNumSubscriptionsToResume)
{
    InteractionModelEngine * engine         = InteractionModelEngine::GetInstance();
    constexpr uint8_t kNumberOfSubsToResume = 5;
    uint8_t numberOfSubsRemaining           = kNumberOfSubsToResume;

    engine->SetDataModelProvider(CodegenDataModelProviderInstance(nullptr /* delegate */));
    EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR);

#if CHIP_CONFIG_ENABLE_ICD_CIP && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
    ICDManager manager;
    engine->SetICDManager(&manager);
#endif // CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION

    // Set number of subs
    engine->mNumOfSubscriptionsToResume = kNumberOfSubsToResume;

#if CHIP_CONFIG_ENABLE_ICD_CIP && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
    // Verify mIsBootUpResumeSubscriptionExecuted has not been set
    EXPECT_FALSE(manager.GetIsBootUpResumeSubscriptionExecuted());
#endif // CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION

    // Decrease number of subs by 1
    numberOfSubsRemaining--;
    engine->DecrementNumSubscriptionsToResume();
    EXPECT_EQ(numberOfSubsRemaining, engine->mNumOfSubscriptionsToResume);

    // Decrease to 0 subs remaining
    while (numberOfSubsRemaining > 0)
    {
#if CHIP_CONFIG_ENABLE_ICD_CIP && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
        // Verify mIsBootUpResumeSubscriptionExecuted has not been set
        EXPECT_FALSE(manager.GetIsBootUpResumeSubscriptionExecuted());
#endif // CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION

        numberOfSubsRemaining--;
        engine->DecrementNumSubscriptionsToResume();
        EXPECT_EQ(numberOfSubsRemaining, engine->mNumOfSubscriptionsToResume);
    }

#if CHIP_CONFIG_ENABLE_ICD_CIP && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
    // Verify mIsBootUpResumeSubscriptionExecuted has been set
    EXPECT_TRUE(manager.GetIsBootUpResumeSubscriptionExecuted());
#endif // CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION

    // Make sure we don't rollover / go negative
    engine->DecrementNumSubscriptionsToResume();
    EXPECT_EQ(numberOfSubsRemaining, engine->mNumOfSubscriptionsToResume);

    // Clean up
#if CHIP_CONFIG_ENABLE_ICD_CIP && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
    engine->SetICDManager(nullptr);
#endif // CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
}
#endif // CHIP_CONFIG_PERSIST_SUBSCRIPTIONS

TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestFabricHasAtLeastOneActiveSubscription)
{
    NullReadHandlerCallback nullCallback;
    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    FabricIndex fabricIndex1 = 1;
    FabricIndex fabricIndex2 = 2;

    // Create ExchangeContexts
    Messaging::ExchangeContext * exchangeCtx1 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx1);

    Messaging::ExchangeContext * exchangeCtx2 = NewExchangeToAlice(nullptr, false);
    ASSERT_TRUE(exchangeCtx2);

    // InteractionModelEngine init
    EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler()));

    // Verify that both fabrics have no active subscriptions
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex1));
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex2));

    // Create and setup readHandler 1
    ReadHandler * readHandler1 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx1, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Verify that fabric 1 still doesn't have an active subscription
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex1));

    // Set readHandler1 to active
    readHandler1->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that fabric 1 has an active subscription
    EXPECT_TRUE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex1));

    // Verify that fabric 2 still doesn't have an active subscription
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex2));

    // Create and setup readHandler 2
    ReadHandler * readHandler2 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx2, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Set readHandler2 to active
    readHandler2->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that fabric 2 has an active subscription
    EXPECT_TRUE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex2));

    // Clean up read handlers
    engine->GetReadHandlerPool().ReleaseAll();

    // Verify that both fabrics have no active subscriptions
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex1));
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex2));
}

TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestFabricHasAtLeastOneActiveSubscriptionWithMixedStates)
{
    NullReadHandlerCallback nullCallback;
    InteractionModelEngine * engine = InteractionModelEngine::GetInstance();

    FabricIndex fabricIndex = 1;

    // Create ExchangeContexts
    Messaging::ExchangeContext * exchangeCtx1 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx1);

    Messaging::ExchangeContext * exchangeCtx2 = NewExchangeToBob(nullptr, false);
    ASSERT_TRUE(exchangeCtx2);

    // InteractionModelEngine init
    EXPECT_EQ(CHIP_NO_ERROR, engine->Init(&GetExchangeManager(), &GetFabricTable(), reporting::GetDefaultReportScheduler()));

    // Verify that the fabric has no active subscriptions
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex));

    // Create and setup readHandler 1
    ReadHandler * readHandler1 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx1, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Verify that the fabric still doesn't have an active subscription
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex));

    // Set readHandler1 to active
    readHandler1->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, true);

    // Verify that the fabric has an active subscription
    EXPECT_TRUE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex));

    // Create and setup readHandler 2
    ReadHandler * readHandler2 = engine->GetReadHandlerPool().CreateObject(
        nullCallback, exchangeCtx2, ReadHandler::InteractionType::Subscribe, reporting::GetDefaultReportScheduler());

    // Verify that the fabric still has an active subscription
    EXPECT_TRUE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex));

    // Set readHandler2 to inactive
    readHandler2->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, false);

    // Verify that the fabric still has an active subscription
    EXPECT_TRUE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex));

    // Set readHandler1 to inactive
    readHandler1->SetStateFlag(ReadHandler::ReadHandlerFlags::ActiveSubscription, false);

    // Verify that the fabric doesn't have an active subscription
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex));

    // Clean up read handlers
    engine->GetReadHandlerPool().ReleaseAll();

    // Verify that the fabric has no active subscriptions
    EXPECT_FALSE(engine->FabricHasAtLeastOneActiveSubscription(fabricIndex));
}

} // namespace app
} // namespace chip
