/*
 *
 *    Copyright (c) 2021-2022 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 <set>
#include <string.h>
#include <tuple>
#include <utility>

#include <pw_unit_test/framework.h>

#include <credentials/GroupDataProviderImpl.h>
#include <crypto/DefaultSessionKeystore.h>
#include <lib/core/StringBuilderAdapters.h>
#include <lib/core/TLV.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/TestPersistentStorageDelegate.h>
#include <lib/support/tests/ExtraPwTestMacros.h>
#include <platform/KeyValueStoreManager.h>

using namespace chip::Credentials;
using GroupInfo      = GroupDataProvider::GroupInfo;
using GroupKey       = GroupDataProvider::GroupKey;
using GroupEndpoint  = GroupDataProvider::GroupEndpoint;
using EpochKey       = GroupDataProvider::EpochKey;
using KeySet         = GroupDataProvider::KeySet;
using GroupSession   = GroupDataProvider::GroupSession;
using SecurityPolicy = GroupDataProvider::SecurityPolicy;

namespace chip {
namespace app {
namespace TestGroups {

static const char kKey1[]   = "abc/def";
static const char kValue1[] = "abc/def";
static const char kValue2[] = "abc/ghi/xyz";
static const size_t kSize1  = strlen(kValue1) + 1;
static const size_t kSize2  = strlen(kValue2) + 1;

constexpr uint16_t kMaxGroupsPerFabric    = 5;
constexpr uint16_t kMaxGroupKeysPerFabric = 4;

// If test cases covering more than 2 fabrics are added, update `ResetProvider` function.
constexpr chip::FabricIndex kFabric1 = 1;
constexpr chip::FabricIndex kFabric2 = 7;

// Currently unused constants that are useful for context
#if 0
static const uint8_t kExampleOperationalRootPublicKey[65] = {
    0x04, 0x4a, 0x9f, 0x42, 0xb1, 0xca, 0x48, 0x40, 0xd3, 0x72, 0x92, 0xbb, 0xc7, 0xf6, 0xa7, 0xe1, 0x1e,
    0x22, 0x20, 0x0c, 0x97, 0x6f, 0xc9, 0x00, 0xdb, 0xc9, 0x8a, 0x7a, 0x38, 0x3a, 0x64, 0x1c, 0xb8, 0x25,
    0x4a, 0x2e, 0x56, 0xd4, 0xe2, 0x95, 0xa8, 0x47, 0x94, 0x3b, 0x4e, 0x38, 0x97, 0xc4, 0xa7, 0x73, 0xe9,
    0x30, 0x27, 0x7b, 0x4d, 0x9f, 0xbe, 0xde, 0x8a, 0x05, 0x26, 0x86, 0xbf, 0xac, 0xfa,
};
static const ByteSpan kExampleOperationalRootPublicKeySpan{ kExampleOperationalRootPublicKey };

constexpr chip::FabricId kFabricId1               = 0x2906C908D115D362;
constexpr chip::FabricId kFabricId2               = 0x5E1C0F1B2C813C7A;
#endif

// kFabricId1/kCompressedFabricIdBuffer1 matches the Compressed Fabric Identifier
// example of spec section `4.3.2.2. Compressed Fabric Identifier`. It is based on
// the public key in `kExampleOperationalRootPublicKey`.
static const uint8_t kCompressedFabricIdBuffer1[] = { 0x87, 0xe1, 0xb0, 0x04, 0xe2, 0x35, 0xa1, 0x30 };
constexpr ByteSpan kCompressedFabricId1(kCompressedFabricIdBuffer1);

static const uint8_t kCompressedFabricIdBuffer2[] = { 0x3f, 0xaa, 0xe2, 0x90, 0x93, 0xd5, 0xaf, 0x45 };
constexpr ByteSpan kCompressedFabricId2(kCompressedFabricIdBuffer2);

constexpr chip::GroupId kGroup1 = kMinApplicationGroupId;
constexpr chip::GroupId kGroup2 = 0x2222;
constexpr chip::GroupId kGroup3 = kMaxApplicationGroupId;
constexpr chip::GroupId kGroup4 = 0x4444;
constexpr chip::GroupId kGroup5 = 0x5555;

constexpr chip::EndpointId kEndpointId0 = 0xee00;
constexpr chip::EndpointId kEndpointId1 = 0xee01;
constexpr chip::EndpointId kEndpointId2 = 0xee02;
constexpr chip::EndpointId kEndpointId3 = 0xee03;
constexpr chip::EndpointId kEndpointId4 = 0xee04;

constexpr uint16_t kKeysetId0 = 0x0;
constexpr uint16_t kKeysetId1 = 0x1111;
constexpr uint16_t kKeysetId2 = 0x2222;
constexpr uint16_t kKeysetId3 = 0x3333;
constexpr uint16_t kKeysetId4 = 0x4444;

static const GroupInfo kGroupInfo1_1(kGroup1, "Group-1.1");
static const GroupInfo kGroupInfo1_2(kGroup2, "Group-1.2");
static const GroupInfo kGroupInfo1_3(kGroup3, "Group-1.3");
static const GroupInfo kGroupInfo2_1(kGroup1, "Group-2.1");
static const GroupInfo kGroupInfo2_2(kGroup2, "Group-2.2");
static const GroupInfo kGroupInfo2_3(kGroup3, "Group-2.3");
static const GroupInfo kGroupInfo3_1(kGroup1, "Group-3.1");
static const GroupInfo kGroupInfo3_2(kGroup2, "Group-3.2");
static const GroupInfo kGroupInfo3_3(kGroup3, "Group-3.3");
static const GroupInfo kGroupInfo3_4(kGroup4, "Group-3.4");
static const GroupInfo kGroupInfo3_5(kGroup4, "Group-3.5");
static const GroupInfo kGroupInfo3_6(kGroup4, "Group-3.5");

static const GroupKey kGroup1Keyset0(kGroup1, kKeysetId0);
static const GroupKey kGroup1Keyset1(kGroup1, kKeysetId1);
static const GroupKey kGroup1Keyset2(kGroup1, kKeysetId2);
static const GroupKey kGroup1Keyset3(kGroup1, kKeysetId3);
static const GroupKey kGroup2Keyset0(kGroup2, kKeysetId0);
static const GroupKey kGroup2Keyset1(kGroup2, kKeysetId1);
static const GroupKey kGroup2Keyset2(kGroup2, kKeysetId2);
static const GroupKey kGroup2Keyset3(kGroup2, kKeysetId3);
static const GroupKey kGroup3Keyset0(kGroup3, kKeysetId0);
static const GroupKey kGroup3Keyset1(kGroup3, kKeysetId1);
static const GroupKey kGroup3Keyset2(kGroup3, kKeysetId2);
static const GroupKey kGroup3Keyset3(kGroup3, kKeysetId3);

static KeySet kKeySet0(kKeysetId0, SecurityPolicy::kCacheAndSync, 3);
static KeySet kKeySet1(kKeysetId1, SecurityPolicy::kTrustFirst, 1);
static KeySet kKeySet2(kKeysetId2, SecurityPolicy::kTrustFirst, 2);
static KeySet kKeySet3(kKeysetId3, SecurityPolicy::kCacheAndSync, 3);
static KeySet kKeySet4(kKeysetId4, SecurityPolicy::kTrustFirst, 1);

uint8_t kZeroKey[EpochKey::kLengthBytes] = { 0 };

class TestListener : public GroupDataProvider::GroupListener
{
public:
    chip::FabricIndex fabric_index = kUndefinedFabricIndex;
    GroupInfo latest;
    size_t added_count   = 0;
    size_t removed_count = 0;

    void Reset()
    {
        fabric_index  = kUndefinedFabricIndex;
        latest        = GroupInfo();
        added_count   = 0;
        removed_count = 0;
    }

    void OnGroupAdded(chip::FabricIndex fabric, const GroupInfo & new_group) override
    {
        fabric_index = fabric;
        latest.Copy(new_group);
        added_count++;
    }
    void OnGroupRemoved(chip::FabricIndex fabric, const GroupInfo & old_group) override
    {
        fabric_index = fabric;
        latest.Copy(old_group);
        removed_count++;
    }
};
static TestListener sListener;

void ResetProvider(GroupDataProvider * provider)
{
    EXPECT_SUCCESS(provider->RemoveFabric(kFabric1).NoErrorIf(CHIP_ERROR_NOT_FOUND));
    EXPECT_SUCCESS(provider->RemoveFabric(kFabric2).NoErrorIf(CHIP_ERROR_NOT_FOUND));
}

bool CompareKeySets(const KeySet & retrievedKeySet, const KeySet & keyset2)
{
    VerifyOrReturnError(retrievedKeySet.policy == keyset2.policy, false);
    VerifyOrReturnError(retrievedKeySet.num_keys_used == keyset2.num_keys_used, false);

    for (int i = 0; i < 3; i++)
    {
        if (i < retrievedKeySet.num_keys_used)
        {
            VerifyOrReturnError(retrievedKeySet.epoch_keys[i].start_time == keyset2.epoch_keys[i].start_time, false);
        }
        else
        {
            VerifyOrReturnError(retrievedKeySet.epoch_keys[i].start_time == 0, false);
        }

        VerifyOrReturnError(0 == memcmp(kZeroKey, retrievedKeySet.epoch_keys[i].key, EpochKey::kLengthBytes), false);
    }
    return true;
}

struct TestGroupDataProvider : public ::testing::Test
{

    static chip::TestPersistentStorageDelegate sDelegate;
    static chip::Crypto::DefaultSessionKeystore sSessionKeystore;
    static GroupDataProviderImpl sProvider;

    constexpr static EpochKey kEpochKeys0[] = {
        { 0x0000000000000000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
        { 0x1111111111111111, { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f } },
        { 0x2222222222222222, { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f } }
    };
    constexpr static EpochKey kEpochKeys1[] = {
        { 0x3333333333333333, { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f } },
        { 0x4444444444444444, { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f } },
        { 0x5555555555555555, { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f } },
    };
    constexpr static EpochKey kEpochKeys2[] = {
        { 0xaaaaaaaaaaaaaaaa, { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf } },
        { 0xbbbbbbbbbbbbbbbb, { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf } },
        { 0xcccccccccccccccc, { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf } },
    };
    constexpr static EpochKey kEpochKeys3[] = {
        { 0xdddddddddddddddd, { 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf } },
        { 0xeeeeeeeeeeeeeeee, { 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef } },
        { 0xffffffffffffffff, { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff } },
    };
    static void SetUpTestSuite()
    {

        EXPECT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR);

        // Initialize Group Data Provider
        sProvider.SetStorageDelegate(&sDelegate);
        sProvider.SetSessionKeystore(&sSessionKeystore);
        sProvider.SetListener(&chip::app::TestGroups::sListener);
        EXPECT_EQ(sProvider.Init(), CHIP_NO_ERROR);
        SetGroupDataProvider(&sProvider);

        memcpy(chip::app::TestGroups::kKeySet0.epoch_keys, kEpochKeys0, sizeof(kEpochKeys0));
        memcpy(chip::app::TestGroups::kKeySet1.epoch_keys, kEpochKeys1, sizeof(kEpochKeys1));
        memcpy(chip::app::TestGroups::kKeySet2.epoch_keys, kEpochKeys2, sizeof(kEpochKeys2));
        memcpy(chip::app::TestGroups::kKeySet3.epoch_keys, kEpochKeys3, sizeof(kEpochKeys3));
    }
    static void TearDownTestSuite()
    {
        GroupDataProvider * provider = GetGroupDataProvider();
        if (nullptr != provider)
        {
            provider->Finish();
        }
        chip::Platform::MemoryShutdown();
    }
};

chip::TestPersistentStorageDelegate TestGroupDataProvider::sDelegate;
chip::Crypto::DefaultSessionKeystore TestGroupDataProvider::sSessionKeystore;
GroupDataProviderImpl TestGroupDataProvider::sProvider(kMaxGroupsPerFabric, kMaxGroupKeysPerFabric);

TEST_F(TestGroupDataProvider, TestStorageDelegate)
{
    chip::TestPersistentStorageDelegate delegate;

    char out[128];
    uint16_t size = static_cast<uint16_t>(sizeof(out));

    EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, delegate.SyncGetKeyValue(kKey1, out, size));

    size = static_cast<uint16_t>(kSize1);
    EXPECT_EQ(delegate.SyncSetKeyValue(kKey1, kValue1, size), CHIP_NO_ERROR);

    size = static_cast<uint16_t>(sizeof(out));
    EXPECT_EQ(delegate.SyncGetKeyValue(kKey1, out, size), CHIP_NO_ERROR);
    EXPECT_EQ(size, kSize1);
    EXPECT_FALSE(memcmp(out, kValue1, kSize1));

    size = static_cast<uint16_t>(kSize2);
    EXPECT_EQ(delegate.SyncSetKeyValue(kKey1, kValue2, size), CHIP_NO_ERROR);

    size = static_cast<uint16_t>(sizeof(out));
    EXPECT_EQ(delegate.SyncGetKeyValue(kKey1, out, size), CHIP_NO_ERROR);
    EXPECT_EQ(size, kSize2);
    EXPECT_FALSE(memcmp(out, kValue2, kSize2));

    EXPECT_EQ(delegate.SyncDeleteKeyValue(kKey1), CHIP_NO_ERROR);

    size = static_cast<uint16_t>(sizeof(out));
    EXPECT_EQ(CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, delegate.SyncGetKeyValue(kKey1, out, size));
}

TEST_F(TestGroupDataProvider, TestGroupInfo)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    GroupInfo group;

    // Set Group Info

    sListener.Reset();

    // Out-of-order
    EXPECT_EQ(CHIP_ERROR_INVALID_ARGUMENT, provider->SetGroupInfoAt(kFabric1, 2, kGroupInfo1_1));

    EXPECT_SUCCESS(provider->SetGroupInfoAt(kFabric1, 0, kGroupInfo1_1));
    EXPECT_SUCCESS(provider->SetGroupInfoAt(kFabric1, 1, kGroupInfo1_2));
    EXPECT_SUCCESS(provider->SetGroupInfoAt(kFabric1, 2, kGroupInfo1_3));
    EXPECT_SUCCESS(provider->SetGroupInfoAt(kFabric2, 0, kGroupInfo2_1));
    EXPECT_SUCCESS(provider->SetGroupInfoAt(kFabric2, 1, kGroupInfo2_2));
    EXPECT_SUCCESS(provider->SetGroupInfoAt(kFabric2, 2, kGroupInfo2_3));

    // Duplicated
    EXPECT_EQ(CHIP_ERROR_DUPLICATE_KEY_ID, provider->SetGroupInfoAt(kFabric1, 3, kGroupInfo1_1));
    EXPECT_EQ(CHIP_ERROR_DUPLICATE_KEY_ID, provider->SetGroupInfoAt(kFabric2, 3, kGroupInfo2_3));

    // Get Group Info

    EXPECT_EQ(CHIP_ERROR_INVALID_FABRIC_INDEX, provider->GetGroupInfoAt(kUndefinedFabricIndex, 0, group));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupInfoAt(kFabric2, 999, group));

    EXPECT_EQ(sListener.latest, kGroupInfo2_3);
    EXPECT_EQ(sListener.added_count, 6u);
    EXPECT_EQ(sListener.removed_count, 0u);

    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 2, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_3);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_2);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 0, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_1);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_2);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 0, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_1);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 2, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_3);

    // Remove Groups

    EXPECT_SUCCESS(provider->RemoveGroupInfo(kFabric1, kGroup3));
    EXPECT_SUCCESS(provider->RemoveGroupInfoAt(kFabric2, 0));
    EXPECT_EQ(sListener.latest, kGroupInfo2_1);
    EXPECT_EQ(sListener.added_count, 6u);
    EXPECT_EQ(sListener.removed_count, 2u);

    // Remaining entries shift up

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupInfoAt(kFabric2, 2, group));
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_3);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 0, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_2);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_2);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 0, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_1);
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupInfoAt(kFabric1, 3, group));

    // Overwrite with new group

    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 2, kGroupInfo3_4), CHIP_NO_ERROR);
    // Replace existing group (implicit group remove)
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 0, kGroupInfo3_4), CHIP_NO_ERROR);

    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 2, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo3_4);

    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 0, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo3_4);
    EXPECT_EQ(sListener.latest, kGroupInfo3_4);
    EXPECT_EQ(sListener.added_count, 8u);
    EXPECT_EQ(sListener.removed_count, 3u);

    // Overwrite existing group, index must match

    EXPECT_EQ(CHIP_ERROR_DUPLICATE_KEY_ID, provider->SetGroupInfoAt(kFabric1, 1, kGroupInfo1_1));
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 1, kGroupInfo2_2), CHIP_NO_ERROR);

    EXPECT_EQ(CHIP_ERROR_DUPLICATE_KEY_ID, provider->SetGroupInfoAt(kFabric2, 1, kGroupInfo3_4));
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 1, kGroupInfo1_3), CHIP_NO_ERROR);

    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_2);

    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_3);
    EXPECT_EQ(sListener.latest, kGroupInfo3_4);
    EXPECT_EQ(sListener.added_count, 8u);
    EXPECT_EQ(sListener.removed_count, 3u);

    // By group_id

    // Override existing
    EXPECT_EQ(provider->SetGroupInfo(kFabric1, kGroupInfo3_5), CHIP_NO_ERROR);
    // New group
    EXPECT_EQ(provider->SetGroupInfo(kFabric2, kGroupInfo3_2), CHIP_NO_ERROR);
    // Not found
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupInfo(kFabric2, kGroup5, group));
    // Existing
    EXPECT_EQ(provider->GetGroupInfo(kFabric2, kGroup2, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo3_2);
    EXPECT_EQ(sListener.latest, kGroupInfo3_2);
    EXPECT_EQ(sListener.added_count, 9u);
    EXPECT_EQ(sListener.removed_count, 3u);
}

TEST_F(TestGroupDataProvider, TestGroupInfoIterator)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    GroupInfo group;

    // Set Group Info

    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 0, kGroupInfo1_3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 1, kGroupInfo1_2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 2, kGroupInfo1_1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 0, kGroupInfo2_1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 1, kGroupInfo2_3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 2, kGroupInfo2_2), CHIP_NO_ERROR);

    // Iterate fabric 1

    GroupInfo expected_f1[]  = { kGroupInfo1_3, kGroupInfo1_2, kGroupInfo1_1 };
    size_t expected_f1_count = sizeof(expected_f1) / sizeof(GroupInfo);

    auto it  = provider->IterateGroupInfo(kFabric1);
    size_t i = 0;
    ASSERT_TRUE(it);
    EXPECT_EQ(expected_f1_count, it->Count());
    while (it->Next(group) && i < expected_f1_count)
    {
        EXPECT_EQ(expected_f1[i++], group);
    }
    EXPECT_EQ(i, it->Count());
    it->Release();

    // Iterate fabric 2

    GroupInfo expected_f2[]  = { kGroupInfo2_1, kGroupInfo2_3, kGroupInfo2_2 };
    size_t expected_f2_count = sizeof(expected_f2) / sizeof(GroupInfo);

    it = provider->IterateGroupInfo(kFabric2);
    ASSERT_TRUE(it);
    i = 0;
    EXPECT_EQ(expected_f2_count, it->Count());
    while (it->Next(group) && i < expected_f2_count)
    {
        EXPECT_EQ(expected_f2[i++], group);
    }
    EXPECT_EQ(i, it->Count());
    it->Release();
}

TEST_F(TestGroupDataProvider, TestEndpoints)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    GroupInfo group;

    // Existing groups

    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 0, kGroupInfo1_1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 1, kGroupInfo1_2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 2, kGroupInfo1_3), CHIP_NO_ERROR);

    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId0));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId1));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId2));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId3));

    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId3), CHIP_NO_ERROR);

    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId2));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId1));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId0));

    // New groups

    EXPECT_FALSE(provider->HasEndpoint(kFabric2, kGroup1, kEndpointId0));
    EXPECT_FALSE(provider->HasEndpoint(kFabric2, kGroup2, kEndpointId1));
    EXPECT_FALSE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId2));
    EXPECT_FALSE(provider->HasEndpoint(kFabric2, kGroup4, kEndpointId3));

    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup1, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup2, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup4, kEndpointId3), CHIP_NO_ERROR);

    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup1, kEndpointId0));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup2, kEndpointId1));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId2));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup4, kEndpointId3));

    // Remove

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->RemoveEndpoint(kFabric1, kGroup1, kEndpointId4));
    EXPECT_EQ(provider->RemoveEndpoint(kFabric1, kGroup1, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->RemoveEndpoint(kFabric1, kGroup2, kEndpointId3), CHIP_NO_ERROR);

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->RemoveEndpoint(kFabric2, kGroup5, kEndpointId0));
    EXPECT_EQ(provider->RemoveEndpoint(kFabric2, kGroup2, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->RemoveEndpoint(kFabric2, kGroup3, kEndpointId2), CHIP_NO_ERROR);

    // Check removed

    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId0));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId1));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId2));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId3));

    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup1, kEndpointId0));
    EXPECT_FALSE(provider->HasEndpoint(kFabric2, kGroup2, kEndpointId1));
    EXPECT_FALSE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId2));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup4, kEndpointId3));

    // Remove All

    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup3, kEndpointId3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup4, kEndpointId3), CHIP_NO_ERROR);

    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId1));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId2));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup3, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup4, kEndpointId3));

    EXPECT_EQ(provider->RemoveEndpoint(kFabric1, kEndpointId3), CHIP_NO_ERROR);

    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId1));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId3));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId2));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup3, kEndpointId3));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup4, kEndpointId3));
}

TEST_F(TestGroupDataProvider, TestEndpointIterator)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    GroupInfo group;

    // Set Endpoints

    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId4), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId3), CHIP_NO_ERROR);

    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId4), CHIP_NO_ERROR);

    // Iterate fabric 1

    std::set<std::pair<GroupId, EndpointId>> expected_f1 = {
        { kGroup1, kEndpointId0 }, { kGroup1, kEndpointId2 }, { kGroup1, kEndpointId4 },
        { kGroup2, kEndpointId1 }, { kGroup2, kEndpointId2 }, { kGroup2, kEndpointId3 },
    };

    auto it      = provider->IterateEndpoints(kFabric1);
    size_t count = 0;
    ASSERT_TRUE(it);
    GroupEndpoint output;
    EXPECT_EQ(expected_f1.size(), it->Count());
    while (it->Next(output) && count < expected_f1.size())
    {
        std::pair<chip::GroupId, chip::EndpointId> mapping(output.group_id, output.endpoint_id);
        EXPECT_GT(expected_f1.count(mapping), 0u);
        count++;
    }
    EXPECT_EQ(count, it->Count());
    it->Release();

    // Iterate fabric 2

    std::set<std::pair<GroupId, EndpointId>> expected_f2 = {
        { kGroup3, kEndpointId0 }, { kGroup3, kEndpointId1 }, { kGroup3, kEndpointId2 },
        { kGroup3, kEndpointId3 }, { kGroup3, kEndpointId4 },
    };

    it = provider->IterateEndpoints(kFabric2);
    ASSERT_TRUE(it);
    count = 0;
    EXPECT_EQ(expected_f2.size(), it->Count());
    while (it->Next(output) && count < expected_f2.size())
    {
        std::pair<chip::GroupId, chip::EndpointId> mapping(output.group_id, output.endpoint_id);
        EXPECT_GT(expected_f2.count(mapping), 0u);
        count++;
    }
    EXPECT_EQ(count, it->Count());
    it->Release();
}

TEST_F(TestGroupDataProvider, TestGroupKeys)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    GroupKey pair;

    // Set Group Info

    // Out-of-order
    EXPECT_EQ(CHIP_ERROR_INVALID_ARGUMENT, provider->SetGroupKeyAt(kFabric1, 2, kGroup1Keyset0));

    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 0, kGroup1Keyset0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 1, kGroup1Keyset1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 2, kGroup1Keyset2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 3, kGroup1Keyset3), CHIP_NO_ERROR);
    // Duplicated
    EXPECT_EQ(CHIP_ERROR_DUPLICATE_KEY_ID, provider->SetGroupKeyAt(kFabric1, 4, kGroup1Keyset2));

    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 0, kGroup2Keyset0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 1, kGroup2Keyset1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 2, kGroup2Keyset2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 3, kGroup2Keyset3), CHIP_NO_ERROR);
    // Duplicated
    EXPECT_EQ(CHIP_ERROR_DUPLICATE_KEY_ID, provider->SetGroupKeyAt(kFabric2, 4, kGroup2Keyset0));

    // Get Group Info

    EXPECT_EQ(CHIP_ERROR_INVALID_FABRIC_INDEX, provider->GetGroupKeyAt(kUndefinedFabricIndex, 0, pair));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupKeyAt(kFabric2, 999, pair));

    EXPECT_EQ(provider->GetGroupKeyAt(kFabric1, 3, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup1Keyset3);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric1, 2, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup1Keyset2);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric1, 1, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup1Keyset1);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric1, 0, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup1Keyset0);

    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 3, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset3);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 2, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset2);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 1, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset1);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 0, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset0);

    // Override first
    EXPECT_EQ(provider->SetGroupKey(kFabric1, kGroup1, kKeysetId3), CHIP_NO_ERROR);
    // Get First
    KeysetId keyset_id = 0;
    EXPECT_EQ(provider->GetGroupKey(kFabric1, kGroup1, keyset_id), CHIP_NO_ERROR);
    EXPECT_EQ(keyset_id, kKeysetId3);

    // Remove Groups (remaining entries shift up)

    EXPECT_EQ(provider->RemoveGroupKeyAt(kFabric1, 2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->RemoveGroupKeyAt(kFabric2, 0), CHIP_NO_ERROR);

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupKeyAt(kFabric1, 3, pair));
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric1, 2, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup1Keyset3);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric1, 1, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup1Keyset1);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric1, 0, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup1Keyset3);

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupKeyAt(kFabric2, 3, pair));
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 2, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset3);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 1, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset2);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 0, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset1);

    // Overwrite, (group_id, keyset_id) must be unique

    EXPECT_EQ(CHIP_ERROR_DUPLICATE_KEY_ID, provider->SetGroupKeyAt(kFabric1, 2, kGroup1Keyset3));
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 2, kGroup3Keyset0), CHIP_NO_ERROR);
    EXPECT_EQ(CHIP_ERROR_DUPLICATE_KEY_ID, provider->SetGroupKeyAt(kFabric2, 0, kGroup2Keyset2));
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 0, kGroup3Keyset1), CHIP_NO_ERROR);

    EXPECT_EQ(provider->GetGroupKeyAt(kFabric1, 2, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup3Keyset0);

    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 0, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup3Keyset1);

    // Remove all

    EXPECT_EQ(provider->RemoveGroupKeys(kFabric1), CHIP_NO_ERROR);

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupKeyAt(kFabric1, 3, pair));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupKeyAt(kFabric1, 2, pair));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupKeyAt(kFabric1, 1, pair));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupKeyAt(kFabric1, 0, pair));

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupKeyAt(kFabric2, 3, pair));
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 2, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset3);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 1, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup2Keyset2);
    EXPECT_EQ(provider->GetGroupKeyAt(kFabric2, 0, pair), CHIP_NO_ERROR);
    EXPECT_EQ(pair, kGroup3Keyset1);
}

TEST_F(TestGroupDataProvider, TestGroupKeyIterator)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    GroupKey pair;

    // Set Group Info

    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 0, kGroup3Keyset0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 1, kGroup3Keyset1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 2, kGroup3Keyset2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 3, kGroup3Keyset3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 4, kGroup1Keyset0), CHIP_NO_ERROR);
    EXPECT_NE(CHIP_NO_ERROR, provider->SetGroupKeyAt(kFabric1, 5, kGroup1Keyset1));

    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 0, kGroup2Keyset0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 1, kGroup2Keyset1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 2, kGroup2Keyset2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 3, kGroup2Keyset3), CHIP_NO_ERROR);

    // Iterate fabric 1

    GroupKey expected_f1[]   = { kGroup3Keyset0, kGroup3Keyset1, kGroup3Keyset2, kGroup3Keyset3, kGroup1Keyset0 };
    size_t expected_f1_count = sizeof(expected_f1) / sizeof(GroupKey);

    auto it      = provider->IterateGroupKeys(kFabric1);
    size_t count = 0;
    ASSERT_TRUE(it);
    EXPECT_EQ(expected_f1_count, it->Count());
    while (it->Next(pair) && count < expected_f1_count)
    {
        EXPECT_EQ(expected_f1[count++], pair);
    }
    EXPECT_EQ(count, it->Count());
    it->Release();

    // Iterate fabric 2

    GroupKey expected_f2[]   = { kGroup2Keyset0, kGroup2Keyset1, kGroup2Keyset2, kGroup2Keyset3 };
    size_t expected_f2_count = sizeof(expected_f2) / sizeof(GroupKey);

    it = provider->IterateGroupKeys(kFabric2);
    ASSERT_TRUE(it);
    count = 0;
    EXPECT_EQ(expected_f2_count, it->Count());
    while (it->Next(pair) && count < expected_f2_count)
    {
        EXPECT_EQ(expected_f2[count++], pair);
    }
    EXPECT_EQ(count, it->Count());
    it->Release();
}

TEST_F(TestGroupDataProvider, TestKeySets)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    KeySet keyset;

    // Add KeySets

    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet3), CHIP_NO_ERROR);
    EXPECT_NE(CHIP_NO_ERROR, provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet4));
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet1), CHIP_NO_ERROR);

    // Get KeySets

    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId3, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet3));

    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId1, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet1));

    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId0, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet0));

    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId2, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet2));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId3, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet3));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId2, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet2));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId1, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet1));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId0, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet0));

    // Remove Keysets

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->RemoveKeySet(kFabric1, 0xffff));

    EXPECT_EQ(provider->RemoveKeySet(kFabric1, kKeysetId1), CHIP_NO_ERROR); // First
    EXPECT_EQ(provider->RemoveKeySet(kFabric1, kKeysetId3), CHIP_NO_ERROR); // Last
    EXPECT_EQ(provider->RemoveKeySet(kFabric2, kKeysetId2), CHIP_NO_ERROR); // Middle

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, kKeysetId3, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, kKeysetId1, keyset));
    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId0, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet0));

    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId2, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet2));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId3, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet3));

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric2, kKeysetId2, keyset));
    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId1, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet1));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId0, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet0));

    // Remove all

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->RemoveKeySet(kFabric1, kKeysetId3));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->RemoveKeySet(kFabric1, kKeysetId1));
    EXPECT_EQ(provider->RemoveKeySet(kFabric1, kKeysetId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->RemoveKeySet(kFabric1, kKeysetId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->RemoveKeySet(kFabric2, kKeysetId3), CHIP_NO_ERROR);
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->RemoveKeySet(kFabric2, kKeysetId2));
    EXPECT_EQ(provider->RemoveKeySet(kFabric2, kKeysetId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->RemoveKeySet(kFabric2, kKeysetId0), CHIP_NO_ERROR);

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, kKeysetId3, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, kKeysetId1, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, kKeysetId0, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, kKeysetId2, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric2, kKeysetId3, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric2, kKeysetId2, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric2, kKeysetId1, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric2, kKeysetId0, keyset));
}

TEST_F(TestGroupDataProvider, TestIpk)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    // Make sure IPK set is not found on a fresh provider
    KeySet ipkOperationalKeySet;
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetIpkKeySet(kFabric1, ipkOperationalKeySet));

    // Add a non-IPK key, make sure the IPK set is not found
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet3), CHIP_NO_ERROR);
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetIpkKeySet(kFabric1, ipkOperationalKeySet));

    const uint8_t kIpkEpochKeyFromSpec[] = { 0x23, 0x5b, 0xf7, 0xe6, 0x28, 0x23, 0xd3, 0x58,
                                             0xdc, 0xa4, 0xba, 0x50, 0xb1, 0x53, 0x5f, 0x4b };

    KeySet fabric1KeySet0(kKeysetId0, SecurityPolicy::kTrustFirst, 1);
    fabric1KeySet0.epoch_keys[0].start_time = 1234;
    memcpy(&fabric1KeySet0.epoch_keys[0].key, &kIpkEpochKeyFromSpec[0], sizeof(kIpkEpochKeyFromSpec));

    // Set a single IPK, validate key derivation follows spec
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, fabric1KeySet0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->GetIpkKeySet(kFabric1, ipkOperationalKeySet), CHIP_NO_ERROR);

    // Make sure the derived key matches spec test vector
    const uint8_t kExpectedIpkFromSpec[] = { 0xa6, 0xf5, 0x30, 0x6b, 0xaf, 0x6d, 0x05, 0x0a,
                                             0xf2, 0x3b, 0xa4, 0xbd, 0x6b, 0x9d, 0xd9, 0x60 };

    EXPECT_EQ(ipkOperationalKeySet.keyset_id, 0u);
    EXPECT_EQ(ipkOperationalKeySet.num_keys_used, 1u);
    EXPECT_EQ(SecurityPolicy::kTrustFirst, ipkOperationalKeySet.policy);
    EXPECT_EQ(ipkOperationalKeySet.epoch_keys[0].start_time, 1234u);
    EXPECT_EQ(memcmp(ipkOperationalKeySet.epoch_keys[0].key, kExpectedIpkFromSpec, sizeof(kExpectedIpkFromSpec)), 0);

    // Remove IPK, verify removal
    EXPECT_EQ(provider->RemoveKeySet(kFabric1, kKeysetId0), CHIP_NO_ERROR);
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetIpkKeySet(kFabric1, ipkOperationalKeySet));

    // Set a single IPK with the SetSingleIpkEpochKey helper, validate key derivation follows spec
    EXPECT_EQ(chip::Credentials::SetSingleIpkEpochKey(provider, kFabric1, ByteSpan(kIpkEpochKeyFromSpec), kCompressedFabricId1),
              CHIP_NO_ERROR);
    EXPECT_EQ(provider->GetIpkKeySet(kFabric1, ipkOperationalKeySet), CHIP_NO_ERROR);

    EXPECT_EQ(ipkOperationalKeySet.keyset_id, 0u);
    EXPECT_EQ(ipkOperationalKeySet.num_keys_used, 1u);
    EXPECT_EQ(SecurityPolicy::kTrustFirst, ipkOperationalKeySet.policy);
    EXPECT_EQ(ipkOperationalKeySet.epoch_keys[0].start_time, 0u); // default time is zero for SetSingleIpkEpochKey
    EXPECT_EQ(memcmp(ipkOperationalKeySet.epoch_keys[0].key, kExpectedIpkFromSpec, sizeof(kExpectedIpkFromSpec)), 0);
}

TEST_F(TestGroupDataProvider, TestKeySetIterator)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    // Add data to iterate
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet1), CHIP_NO_ERROR);

    // Iterate Fabric 1

    KeySet keyset;

    std::map<uint16_t, const KeySet> expected_f1{
        { kKeysetId0, kKeySet0 }, { kKeysetId1, kKeySet1 }, { kKeysetId2, kKeySet2 }, { kKeysetId3, kKeySet3 }
    };

    auto it = provider->IterateKeySets(kFabric1);
    ASSERT_TRUE(it);
    size_t count = 0;
    EXPECT_EQ(expected_f1.size(), it->Count());

    while (it->Next(keyset) && count < expected_f1.size())
    {
        EXPECT_GT(expected_f1.count(keyset.keyset_id), 0u);
        EXPECT_TRUE(CompareKeySets(keyset, expected_f1[keyset.keyset_id]));
        count++;
    }
    EXPECT_EQ(count, expected_f1.size());
    it->Release();

    // Iterate Fabric 2

    std::map<uint16_t, const KeySet> expected_f2{ { kKeysetId1, kKeySet1 }, { kKeysetId2, kKeySet2 }, { kKeysetId3, kKeySet3 } };

    it = provider->IterateKeySets(kFabric2);
    ASSERT_TRUE(it);
    count = 0;
    EXPECT_EQ(expected_f2.size(), it->Count());

    while (it->Next(keyset) && count < expected_f2.size())
    {
        EXPECT_GT(expected_f2.count(keyset.keyset_id), 0u);
        EXPECT_TRUE(CompareKeySets(keyset, expected_f2[keyset.keyset_id]));
        count++;
    }
    EXPECT_EQ(count, expected_f2.size());
    it->Release();
}

TEST_F(TestGroupDataProvider, TestPerFabricData)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    // Group Info
    GroupInfo group;

    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 0, kGroupInfo1_3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 1, kGroupInfo1_2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 2, kGroupInfo1_1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 0, kGroupInfo2_1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 1, kGroupInfo2_3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 2, kGroupInfo2_2), CHIP_NO_ERROR);

    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 0, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_3);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_2);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric1, 2, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo1_1);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 0, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_1);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_3);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 2, group), CHIP_NO_ERROR);
    EXPECT_EQ(group, kGroupInfo2_2);

    // Endpoints

    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId4), CHIP_NO_ERROR);

    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId0));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId1));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId2));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId1));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId2));
    EXPECT_TRUE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId0));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId1));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId2));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId4));

    // Keys

    KeySet keyset;

    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet0), CHIP_NO_ERROR);

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId0, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet0));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId1, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet1));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId2, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet2));

    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId2, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet2));

    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId1, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet1));

    EXPECT_EQ(provider->GetKeySet(kFabric1, kKeysetId0, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet0));

    //
    // Remove Fabric
    //

    EXPECT_EQ(provider->RemoveFabric(kFabric1), CHIP_NO_ERROR);

    // Endpoints

    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId0));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId1));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup1, kEndpointId2));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId1));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId2));
    EXPECT_FALSE(provider->HasEndpoint(kFabric1, kGroup2, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId0));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId1));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId2));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId3));
    EXPECT_TRUE(provider->HasEndpoint(kFabric2, kGroup3, kEndpointId4));

    // Group Info

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupInfoAt(kFabric1, 0, group));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupInfoAt(kFabric1, 1, group));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetGroupInfoAt(kFabric1, 2, group));
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 0, group), CHIP_NO_ERROR);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 1, group), CHIP_NO_ERROR);
    EXPECT_EQ(provider->GetGroupInfoAt(kFabric2, 2, group), CHIP_NO_ERROR);

    // Keys

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId1, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet1));

    EXPECT_EQ(provider->GetKeySet(kFabric2, kKeysetId0, keyset), CHIP_NO_ERROR);
    EXPECT_TRUE(CompareKeySets(keyset, kKeySet0));

    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, 202, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, 404, keyset));
    EXPECT_EQ(CHIP_ERROR_NOT_FOUND, provider->GetKeySet(kFabric1, 606, keyset));
}

TEST_F(TestGroupDataProvider, TestGroupDecryption)
{
    GroupDataProvider * provider = GetGroupDataProvider();
    EXPECT_TRUE(provider);

    // Reset test
    ResetProvider(provider);

    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 0, kGroupInfo1_3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 1, kGroupInfo1_2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric1, 2, kGroupInfo1_1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 0, kGroupInfo2_1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 1, kGroupInfo2_3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupInfoAt(kFabric2, 2, kGroupInfo2_2), CHIP_NO_ERROR);

    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup1, kEndpointId4), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric1, kGroup2, kEndpointId3), CHIP_NO_ERROR);

    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId3), CHIP_NO_ERROR);
    EXPECT_EQ(provider->AddEndpoint(kFabric2, kGroup3, kEndpointId4), CHIP_NO_ERROR);

    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric1, kCompressedFabricId1, kKeySet2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetKeySet(kFabric2, kCompressedFabricId2, kKeySet3), CHIP_NO_ERROR);

    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 0, kGroup1Keyset0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 1, kGroup1Keyset2), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 2, kGroup3Keyset0), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric1, 3, kGroup3Keyset2), CHIP_NO_ERROR);

    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 0, kGroup2Keyset1), CHIP_NO_ERROR);
    EXPECT_EQ(provider->SetGroupKeyAt(kFabric2, 1, kGroup2Keyset3), CHIP_NO_ERROR);

    const size_t kMessageLength            = 10;
    const uint8_t kMessage[kMessageLength] = { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9 };
    const uint8_t nonce[13]                = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x1a, 0x1b, 0x1c };
    const uint8_t aad[40]                  = { 0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0x0b, 0x1b, 0x2b, 0x3b,
                                               0x4b, 0x5b, 0x6b, 0x7b, 0x8b, 0x9b, 0x0c, 0x1c, 0x2c, 0x3c, 0x4c, 0x5c, 0x6c, 0x7c,
                                               0x8c, 0x9c, 0x0d, 0x1d, 0x2d, 0x3d, 0x4d, 0x5d, 0x6d, 0x7d, 0x8d, 0x9d };
    uint8_t mic[16]                        = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    };

    uint8_t ciphertext_buffer[kMessageLength];
    uint8_t plaintext_buffer[kMessageLength];
    MutableByteSpan ciphertext(ciphertext_buffer, sizeof(ciphertext_buffer));
    MutableByteSpan plaintext(plaintext_buffer, sizeof(plaintext_buffer));
    MutableByteSpan tag(mic, sizeof(mic));

    //
    // Encrypt
    //

    // Load the plaintext to encrypt
    memcpy(plaintext_buffer, kMessage, sizeof(kMessage));

    // Get the key context
    Crypto::SymmetricKeyContext * key_context = provider->GetKeyContext(kFabric2, kGroup2);
    ASSERT_NE(nullptr, key_context);
    uint16_t session_id = key_context->GetKeyHash();

    // Encrypt the message
    EXPECT_EQ(key_context->MessageEncrypt(plaintext, ByteSpan(aad, sizeof(aad)), ByteSpan(nonce, sizeof(nonce)), tag, ciphertext),
              CHIP_NO_ERROR);

    // The ciphertext must be different to the original message
    EXPECT_TRUE(memcmp(ciphertext.data(), kMessage, sizeof(kMessage)));
    key_context->Release();

    //
    // Decrypt
    //

    const std::set<std::pair<FabricIndex, GroupId>> expected = { { kFabric2, kGroup2 } };

    // Iterate all keys that matches the incoming session
    GroupSession session;
    auto it      = provider->IterateGroupSessions(session_id);
    size_t count = 0, total = 0;

    ASSERT_TRUE(it);
    total = it->Count();
    EXPECT_EQ(expected.size(), total);
    while (it->Next(session))
    {
        std::pair<FabricIndex, GroupId> found(session.fabric_index, session.group_id);
        EXPECT_GT(expected.count(found), 0u);
        ASSERT_NE(session.keyContext, nullptr);
        // Assert aboves doesn't actually exit, we call continue so that we can call it->Release() outside of
        // loop.
        if (session.keyContext == nullptr)
        {
            continue;
        }

        // Decrypt the ciphertext
        EXPECT_EQ(session.keyContext->MessageDecrypt(ciphertext, ByteSpan(aad, sizeof(aad)), ByteSpan(nonce, sizeof(nonce)), tag,
                                                     plaintext),
                  CHIP_NO_ERROR);

        // The new plaintext must match the original message
        EXPECT_EQ(memcmp(plaintext.data(), kMessage, sizeof(kMessage)), 0);
        count++;
    }
    EXPECT_EQ(count, total);
    it->Release();
}

} // namespace TestGroups
} // namespace app
} // namespace chip

namespace {} // namespace
