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

    engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1);
    ASSERT_NE(attributePathParamsList, nullptr);
    EXPECT_EQ(attributePathParams1.mEndpointId, attributePathParamsList->mValue.mEndpointId);
    EXPECT_EQ(GetAttributePathListLength(attributePathParamsList), 1);

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

    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::Test::kMockEndpoint3;
    attributePathParams1.mClusterId   = chip::Test::MockClusterId(2);
    attributePathParams1.mAttributeId = chip::Test::MockAttributeId(1);

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

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

    engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1);
    engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2);
    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::Test::kMockEndpoint3;
    attributePathParams2.mClusterId   = chip::Test::MockClusterId(2);
    attributePathParams2.mAttributeId = chip::Test::MockAttributeId(2);

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

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

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

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

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

    // 1st is wildcard one, but not intersect with the latter two concrete paths, so the paths in total are 3 finally
    engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1);
    engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams2);
    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::Test::kMockEndpoint3;
    attributePathParams2.mClusterId   = kInvalidClusterId;
    attributePathParams2.mAttributeId = kInvalidAttributeId;

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

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

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

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

    // 1st path is wildcard endpoint, 2nd path is invalid attribute
    engine->PushFrontAttributePathList(attributePathParamsList, attributePathParams1);
    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
    subscriptionStorage.DeleteAll(fabric1);
    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
