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

/**
 *    @file
 *      This file implements unit tests for FabricTable implementation.
 */

#include <errno.h>
#include <nlunit-test.h>

#include <lib/core/CHIPCore.h>

#include <credentials/FabricTable.h>

#include <credentials/PersistentStorageOpCertStore.h>
#include <credentials/TestOnlyLocalCertificateAuthority.h>
#include <credentials/tests/CHIPCert_test_vectors.h>
#include <crypto/CHIPCryptoPAL.h>
#include <crypto/PersistentStorageOperationalKeystore.h>
#include <lib/asn1/ASN1.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/TestPersistentStorageDelegate.h>
#include <lib/support/UnitTestExtendedAssertions.h>
#include <lib/support/UnitTestRegistration.h>
#include <platform/ConfigurationManager.h>

#include <lib/support/BytesToHex.h>

#include <stdarg.h>

using namespace chip;
using namespace chip::Credentials;

namespace {

class ScopedFabricTable
{
public:
    ScopedFabricTable() {}
    ~ScopedFabricTable()
    {
        mFabricTable.Shutdown();
        mOpCertStore.Finish();
        mOpKeyStore.Finish();
    }

    CHIP_ERROR Init(chip::TestPersistentStorageDelegate * storage)
    {
        chip::FabricTable::InitParams initParams;
        initParams.storage             = storage;
        initParams.operationalKeystore = &mOpKeyStore;
        initParams.opCertStore         = &mOpCertStore;

        ReturnErrorOnFailure(mOpKeyStore.Init(storage));
        ReturnErrorOnFailure(mOpCertStore.Init(storage));
        return mFabricTable.Init(initParams);
    }

    FabricTable & GetFabricTable() { return mFabricTable; }

private:
    chip::FabricTable mFabricTable;
    chip::PersistentStorageOperationalKeystore mOpKeyStore;
    chip::Credentials::PersistentStorageOpCertStore mOpCertStore;
};

/**
 * Load a single test fabric with with the Root01:ICA01:Node01_01 identity.
 */
static CHIP_ERROR LoadTestFabric_Node01_01(nlTestSuite * inSuite, FabricTable & fabricTable, bool doCommit)
{
    Crypto::P256SerializedKeypair opKeysSerialized;
    static Crypto::P256Keypair opKey_Node01_01;

    FabricIndex fabricIndex;
    memcpy(opKeysSerialized.Bytes(), TestCerts::sTestCert_Node01_01_PublicKey.data(),
           TestCerts::sTestCert_Node01_01_PublicKey.size());
    memcpy(opKeysSerialized.Bytes() + TestCerts::sTestCert_Node01_01_PublicKey.size(),
           TestCerts::sTestCert_Node01_01_PrivateKey.data(), TestCerts::sTestCert_Node01_01_PrivateKey.size());

    ByteSpan rcacSpan(TestCerts::sTestCert_Root01_Chip);
    ByteSpan icacSpan(TestCerts::sTestCert_ICA01_Chip);
    ByteSpan nocSpan(TestCerts::sTestCert_Node01_01_Chip);

    ReturnErrorOnFailure(opKeysSerialized.SetLength(TestCerts::sTestCert_Node01_01_PublicKey.size() +
                                                    TestCerts::sTestCert_Node01_01_PrivateKey.size()));
    ReturnErrorOnFailure(opKey_Node01_01.Deserialize(opKeysSerialized));
    ReturnErrorOnFailure(fabricTable.AddNewPendingTrustedRootCert(rcacSpan));

    ReturnErrorOnFailure(fabricTable.AddNewPendingFabricWithProvidedOpKey(nocSpan, icacSpan, VendorId::TestVendor1,
                                                                          &opKey_Node01_01,
                                                                          /*isExistingOpKeyExternallyOwned =*/true, &fabricIndex));
    if (doCommit)
    {
        ReturnErrorOnFailure(fabricTable.CommitPendingFabricData());
    }

    return CHIP_NO_ERROR;
}

static CHIP_ERROR LoadTestFabric_Node01_02(nlTestSuite * inSuite, FabricTable & fabricTable, bool doCommit)
{
    Crypto::P256SerializedKeypair opKeysSerialized;
    FabricIndex fabricIndex;
    static Crypto::P256Keypair opKey_Node01_02;

    memcpy(opKeysSerialized.Bytes(), TestCerts::sTestCert_Node01_02_PublicKey.data(),
           TestCerts::sTestCert_Node01_02_PublicKey.size());
    memcpy(opKeysSerialized.Bytes() + TestCerts::sTestCert_Node01_02_PublicKey.size(),
           TestCerts::sTestCert_Node01_02_PrivateKey.data(), TestCerts::sTestCert_Node01_02_PrivateKey.size());

    ByteSpan rcacSpan(TestCerts::sTestCert_Root01_Chip);
    ByteSpan nocSpan(TestCerts::sTestCert_Node01_02_Chip);

    ReturnErrorOnFailure(opKeysSerialized.SetLength(TestCerts::sTestCert_Node01_02_PublicKey.size() +
                                                    TestCerts::sTestCert_Node01_02_PrivateKey.size()));
    ReturnErrorOnFailure(opKey_Node01_02.Deserialize(opKeysSerialized));

    ReturnErrorOnFailure(fabricTable.AddNewPendingTrustedRootCert(rcacSpan));

    ReturnErrorOnFailure(fabricTable.AddNewPendingFabricWithProvidedOpKey(nocSpan, {}, VendorId::TestVendor1, &opKey_Node01_02,
                                                                          /*isExistingOpKeyExternallyOwned =*/true, &fabricIndex));
    if (doCommit)
    {
        ReturnErrorOnFailure(fabricTable.CommitPendingFabricData());
    }

    return CHIP_NO_ERROR;
}

/**
 * Load a single test fabric with with the Root02:ICA02:Node02_01 identity.
 */
static CHIP_ERROR LoadTestFabric_Node02_01(nlTestSuite * inSuite, FabricTable & fabricTable, bool doCommit,
                                           FabricTable::AdvertiseIdentity advertiseIdentity = FabricTable::AdvertiseIdentity::Yes)
{
    Crypto::P256SerializedKeypair opKeysSerialized;
    FabricIndex fabricIndex;
    static Crypto::P256Keypair opKey_Node02_01;

    memcpy(opKeysSerialized.Bytes(), TestCerts::sTestCert_Node02_01_PublicKey.data(),
           TestCerts::sTestCert_Node02_01_PublicKey.size());
    memcpy(opKeysSerialized.Bytes() + TestCerts::sTestCert_Node02_01_PublicKey.size(),
           TestCerts::sTestCert_Node02_01_PrivateKey.data(), TestCerts::sTestCert_Node02_01_PrivateKey.size());

    ByteSpan rcacSpan(TestCerts::sTestCert_Root02_Chip);
    ByteSpan icacSpan(TestCerts::sTestCert_ICA02_Chip);
    ByteSpan nocSpan(TestCerts::sTestCert_Node02_01_Chip);

    NL_TEST_ASSERT(inSuite,
                   opKeysSerialized.SetLength(TestCerts::sTestCert_Node02_01_PublicKey.size() +
                                              TestCerts::sTestCert_Node02_01_PrivateKey.size()) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, opKey_Node02_01.Deserialize(opKeysSerialized) == CHIP_NO_ERROR);

    NL_TEST_ASSERT(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcacSpan) == CHIP_NO_ERROR);

    CHIP_ERROR err =
        fabricTable.AddNewPendingFabricWithProvidedOpKey(nocSpan, icacSpan, VendorId::TestVendor1, &opKey_Node02_01,
                                                         /*isExistingOpKeyExternallyOwned =*/true, &fabricIndex, advertiseIdentity);
    NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);

    if (doCommit)
    {
        err = fabricTable.CommitPendingFabricData();
        NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
    }

    return err;
}
void TestLastKnownGoodTimeInit(nlTestSuite * inSuite, void * inContext)
{
    // Fabric table init should init Last Known Good Time to the firmware build time.
    chip::TestPersistentStorageDelegate testStorage;
    ScopedFabricTable fabricTableHolder;

    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
    System::Clock::Seconds32 lastKnownGoodChipEpochTime;

    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
    NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodChipEpochTime) == CHIP_NO_ERROR);
    System::Clock::Seconds32 firmwareBuildTime;
    NL_TEST_ASSERT(inSuite, DeviceLayer::ConfigurationMgr().GetFirmwareBuildChipEpochTime(firmwareBuildTime) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, lastKnownGoodChipEpochTime == firmwareBuildTime);
}

void TestCollidingFabrics(nlTestSuite * inSuite, void * inContext)
{
    chip::TestPersistentStorageDelegate testStorage;
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    //
    // Start by loading NOCs for two nodes on the same fabric. The second one should fail since the FabricTable by default
    // doesn't permit colliding fabrics.
    //
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_02(inSuite, fabricTable, /* doCommit = */ true) != CHIP_NO_ERROR);

    //
    // Revert the partially added NOC from the last call, permit colliding fabrics in the FabricTable and try again.
    // This time, it should succeed
    //
    fabricTable.RevertPendingFabricData();
    fabricTable.PermitCollidingFabrics();
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_02(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);

    ByteSpan rcacSpan(TestCerts::sTestCert_Root01_Chip);
    Credentials::P256PublicKeySpan rootPublicKeySpan;

    NL_TEST_ASSERT(inSuite, Credentials::ExtractPublicKeyFromChipCert(rcacSpan, rootPublicKeySpan) == CHIP_NO_ERROR);

    //
    // Ensure we can find both node identities in the FabricTable.
    //
    {
        chip::Platform::ScopedMemoryBuffer<uint8_t> nocBuf;
        ByteSpan origNocSpan(TestCerts::sTestCert_Node01_01_Chip);
        NodeId nodeId;
        FabricId fabricId;

        NL_TEST_ASSERT(inSuite, ExtractNodeIdFabricIdFromOpCert(origNocSpan, &nodeId, &fabricId) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(inSuite, fabricTable.FindIdentity(rootPublicKeySpan, fabricId, nodeId) != nullptr);
    }

    {
        chip::Platform::ScopedMemoryBuffer<uint8_t> nocBuf;
        ByteSpan origNocSpan(TestCerts::sTestCert_Node01_02_Chip);
        NodeId nodeId;
        FabricId fabricId;

        NL_TEST_ASSERT(inSuite, ExtractNodeIdFabricIdFromOpCert(origNocSpan, &nodeId, &fabricId) == CHIP_NO_ERROR);
        NL_TEST_ASSERT(inSuite, fabricTable.FindIdentity(rootPublicKeySpan, fabricId, nodeId) != nullptr);
    }
}

void TestUpdateLastKnownGoodTime(nlTestSuite * inSuite, void * inContext)
{
    // Adding a fabric should advance Last Known Good Time if any certificate's
    // NotBefore time is later than the build time, and else should leave it
    // to the initial build time value.

    // Test certs all have this NotBefore: Oct 15 14:23:43 2020 GMT
    const ASN1::ASN1UniversalTime asn1Expected = { 2020, 10, 15, 14, 23, 43 };
    uint32_t testCertNotBeforeSeconds;
    NL_TEST_ASSERT(inSuite, Credentials::ASN1ToChipEpochTime(asn1Expected, testCertNotBeforeSeconds) == CHIP_NO_ERROR);
    System::Clock::Seconds32 testCertNotBeforeTime = System::Clock::Seconds32(testCertNotBeforeSeconds);

    // Test that certificate NotBefore times that are before the Firmware build time
    // do not advance Last Known Good Time.
    System::Clock::Seconds32 afterNotBeforeBuildTimes[] = { System::Clock::Seconds32(testCertNotBeforeTime.count() + 1),
                                                            System::Clock::Seconds32(testCertNotBeforeTime.count() + 1000),
                                                            System::Clock::Seconds32(testCertNotBeforeTime.count() + 1000000) };
    for (auto buildTime : afterNotBeforeBuildTimes)
    {
        // Set build time to the desired value.
        NL_TEST_ASSERT(inSuite, DeviceLayer::ConfigurationMgr().SetFirmwareBuildChipEpochTime(buildTime) == CHIP_NO_ERROR);
        chip::TestPersistentStorageDelegate testStorage;

        {
            // Initialize a fabric table.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Read back Last Known Good Time, which will have been initialized to firmware build time.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);

            // Load a test fabric, but do not commit.
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ false) == CHIP_NO_ERROR);

            // Read Last Known Good Time and verify that it hasn't moved forward.
            // This test case was written after the test certs' NotBefore time and we
            // are using a configuration manager that should reflect a real build time.
            // Therefore, we expect that build time is after NotBefore and so Last
            // Known Good Time will be set to the later of these, build time, even
            // after installing the new fabric.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);

            // Verify that calling the fail-safe roll back interface does not change
            // last known good time, as it hadn't been updated in the first place.
            fabricTable.RevertPendingFabricData();
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);

            // Now reload the test fabric and commit this time.
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);

            // Read Last Known Good Time and verify that it hasn't moved forward.
            // This test case was written after the test certs' NotBefore time and we
            // are using a configuration manager that should reflect a real build time.
            // Therefore, we expect that build time is after NotBefore and so Last
            // Known Good Time will be set to the later of these, build time, even
            // after installing the new fabric.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);

            // Call revert again.  Since we've committed, this is a no-op.
            // Last known good time should again be unchanged.
            fabricTable.RevertPendingFabricData();
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);
        }
        {
            // Test reloading last known good time from persistence.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Verify that last known good time was retained.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);
        }
    }

    System::Clock::Seconds32 beforeNotBeforeBuildTimes[] = { testCertNotBeforeTime,
                                                             System::Clock::Seconds32(testCertNotBeforeTime.count() - 1),
                                                             System::Clock::Seconds32(testCertNotBeforeTime.count() - 1000),
                                                             System::Clock::Seconds32(testCertNotBeforeTime.count() - 1000000) };
    // Test that certificate NotBefore times that are at or after the Firmware
    // build time do result in Last Known Good Times set to these.
    // Verify behavior both for fail-safe roll back and commit scenarios.
    for (auto buildTime : beforeNotBeforeBuildTimes)
    {
        // Set build time to the desired value.
        NL_TEST_ASSERT(inSuite, DeviceLayer::ConfigurationMgr().SetFirmwareBuildChipEpochTime(buildTime) == CHIP_NO_ERROR);
        chip::TestPersistentStorageDelegate testStorage;
        {
            // Initialize a fabric table.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Load a test fabric, but do not commit.
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ false) == CHIP_NO_ERROR);

            // Read Last Known Good Time and verify that it is now set to the certificate
            // NotBefore time, as this should be at or after firmware build time.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == testCertNotBeforeTime);

            // Now test revert.  Last known good time should change back to the
            // previous value.
            fabricTable.RevertPendingFabricData();
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == buildTime);
        }
        {
            // Test reloading last known good time from persistence.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Verify that the original last known good time was retained, since
            // we reverted before.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
        }
        {
            // Now test loading a fabric and committing.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);

            // Read Last Known Good Time and verify that it is now set to the certificate
            // NotBefore time, as this should be at or after firmware build time.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == testCertNotBeforeTime);

            // Now test revert, which will be a no-op because we already
            // committed.  Verify that Last Known Good time is retained.
            fabricTable.RevertPendingFabricData();
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == testCertNotBeforeTime);
        }
        {
            // Test reloading last known good time from persistence.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Verify that the new last known good time was retained, since
            // we committed.
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == testCertNotBeforeTime);
        }
    }
}

void TestSetLastKnownGoodTime(nlTestSuite * inSuite, void * inContext)
{
    // It is desirable for nodes to set Last Known Good Time whenever a good
    // time source is available, including cases where this would set the time
    // backward.  However, it is impermissible to set last known good time to
    // any time before the Firmware Build time or the latest NotBefore of any
    // installed certificate.

    // Test certs all have this NotBefore: Oct 15 14:23:43 2020 GMT
    const ASN1::ASN1UniversalTime asn1Expected = { 2020, 10, 15, 14, 23, 43 };
    uint32_t testCertNotBeforeSeconds;
    NL_TEST_ASSERT(inSuite, Credentials::ASN1ToChipEpochTime(asn1Expected, testCertNotBeforeSeconds) == CHIP_NO_ERROR);
    System::Clock::Seconds32 testCertNotBeforeTime = System::Clock::Seconds32(testCertNotBeforeSeconds);

    // Iterate over two cases: one with build time prior to our certificates' NotBefore, one with build time after.
    System::Clock::Seconds32 testCaseFirmwareBuildTimes[] = { System::Clock::Seconds32(testCertNotBeforeTime.count() - 100000),
                                                              System::Clock::Seconds32(testCertNotBeforeTime.count() + 100000) };

    for (auto buildTime : testCaseFirmwareBuildTimes)
    {
        // Set build time to the desired value.
        NL_TEST_ASSERT(inSuite, DeviceLayer::ConfigurationMgr().SetFirmwareBuildChipEpochTime(buildTime) == CHIP_NO_ERROR);
        chip::TestPersistentStorageDelegate testStorage;
        System::Clock::Seconds32 newTime;
        {
            // Initialize a fabric table.
            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            // Load a test fabric
            NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit= */ true) == CHIP_NO_ERROR);

            // Verify the Last Known Good Time matches our expected initial value.
            System::Clock::Seconds32 initialLastKnownGoodTime =
                buildTime > testCertNotBeforeTime ? buildTime : testCertNotBeforeTime;
            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Read Last Known Good Time and verify that it hasn't moved forward, since
            // build time is later than the test certs' NotBefore times.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Attempt to set a Last Known Good Time that is before the firmware build time.  This should fail.
            newTime = System::Clock::Seconds32(buildTime.count() - 1000);
            NL_TEST_ASSERT(inSuite, fabricTable.SetLastKnownGoodChipEpochTime(newTime) != CHIP_NO_ERROR);

            // Verify Last Known Good Time is unchanged.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Attempt to set a Last Known Good Time that is before our certificates' NotBefore times.  This should fail.
            newTime = System::Clock::Seconds32(testCertNotBeforeTime.count() - 1000);
            NL_TEST_ASSERT(inSuite, fabricTable.SetLastKnownGoodChipEpochTime(newTime) != CHIP_NO_ERROR);

            // Verify Last Known Good Time is unchanged.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Attempt to set a Last Known Good Time that at our current value.
            NL_TEST_ASSERT(inSuite, fabricTable.SetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);

            // Verify Last Known Good Time is unchanged.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == initialLastKnownGoodTime);

            // Attempt to set Last Known Good Times that is after our current value.
            newTime = System::Clock::Seconds32(initialLastKnownGoodTime.count() + 1000);
            NL_TEST_ASSERT(inSuite, fabricTable.SetLastKnownGoodChipEpochTime(newTime) == CHIP_NO_ERROR);

            // Verify Last Known Good Time is updated.
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == newTime);
        }
        {
            // Verify that Last Known Good Time was persisted.

            ScopedFabricTable fabricTableHolder;
            NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
            FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

            System::Clock::Seconds32 lastKnownGoodTime;
            NL_TEST_ASSERT(inSuite, fabricTable.GetLastKnownGoodChipEpochTime(lastKnownGoodTime) == CHIP_NO_ERROR);
            NL_TEST_ASSERT(inSuite, lastKnownGoodTime == newTime);
        }
    }
}

// Test adding 2 fabrics, updating 1, removing 1
void TestBasicAddNocUpdateNocFlow(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabric11CertAuthority;
    Credentials::TestOnlyLocalCertificateAuthority fabric44CertAuthority;

    chip::TestPersistentStorageDelegate storage;

    // Uncomment the next line for superior debugging powers if you blow-up this test
    // storage.SetLoggingLevel(chip::TestPersistentStorageDelegate::LoggingLevel::kLogMutation);

    // Initialize test CA and a Fabric 11 externally owned key
    NL_TEST_ASSERT(inSuite, fabric11CertAuthority.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, fabric44CertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    chip::Crypto::P256Keypair fabric11Node55Keypair; // Fabric ID 11,
    NL_TEST_ASSERT(inSuite, fabric11Node55Keypair.Initialize(Crypto::ECPKeyTarget::ECDSA) == CHIP_NO_ERROR);

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    {
        FabricIndex nextFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
        NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 1);
    }

    size_t numFabricsIterated = 0;

    size_t numStorageKeysAtStart = storage.GetNumKeys();

    // Sequence 1: Add node ID 55 on fabric 11, using externally owned key and no ICAC --> Yield fabricIndex 1
    {
        FabricId fabricId = 11;
        NodeId nodeId     = 55;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric11CertAuthority.SetIncludeIcac(false)
                                   .GenerateNocChain(fabricId, nodeId, fabric11Node55Keypair.Pubkey())
                                   .GetStatus());
        ByteSpan rcac = fabric11CertAuthority.GetRcac();
        ByteSpan noc  = fabric11CertAuthority.GetNoc();

        // Validate iterator sees nothing yet
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 0);
            NL_TEST_ASSERT(inSuite, saw1 == false);
        }

        uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
        {
            // No pending root cert yet.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan) == CHIP_ERROR_NOT_FOUND);
        }

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        {
            // Now have a pending root cert.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan));
            NL_TEST_ASSERT(inSuite, fetchedSpan.data_equal(rcac));
        }

        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        bool keyIsExternallyOwned  = true;

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithProvidedOpKey(noc, ByteSpan{}, kVendorId, &fabric11Node55Keypair,
                                                                                keyIsExternallyOwned, &newFabricIndex));
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        {
            // No more pending root cert; it's associated with a fabric now.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan) == CHIP_ERROR_NOT_FOUND);
        }

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAtStart);

        // Next fabric index has not been updated yet.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 1);
        }

        // Validate iterator sees pending
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == nodeId);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == fabricId);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == (numStorageKeysAtStart + 4)); // 2 opcerts + fabric metadata + index

        // Next fabric index has been updated.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 2);
        }

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == newFabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        Crypto::P256ECDSASignature sig;
        uint8_t message[] = { 'm', 's', 'g' };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric11Node55Keypair.Pubkey().ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));

        // Validate iterator sees committed
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == nodeId);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == fabricId);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }

    size_t numStorageAfterFirstAdd = storage.GetNumKeys();

    // Sequence 2: Add node ID 999 on fabric 44, using operational keystore and ICAC --> Yield fabricIndex 2
    {
        FabricId fabricId = 44;
        NodeId nodeId     = 999;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan icac = fabric44CertAuthority.GetIcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // Next fabric index should still be the same as before.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 2);
        }

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 2);
        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterFirstAdd);
        // Next fabric index has not been updated yet.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 2);
        }

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(),
                              (numStorageAfterFirstAdd + 5)); // 3 opcerts + fabric metadata + 1 operational key

        // Next fabric index has been updated.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == newFabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Verify we can now see 2 fabrics with the iterator
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            bool saw2          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 11);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }
    }

    size_t numStorageAfterSecondAdd = storage.GetNumKeys();

    // Sequence 3: Update node ID 999 to 1000 on fabric 44, using operational keystore and no ICAC --> Stays fabricIndex 2
    {
        FabricId fabricId       = 44;
        NodeId nodeId           = 1000;
        FabricIndex fabricIndex = 2;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };

        // Make sure to tag fabric index to pending opkey: otherwise the UpdateNOC fails
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AllocatePendingOperationalKey(chip::MakeOptional(static_cast<FabricIndex>(2)), csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT_SUCCESS(
            inSuite,
            fabricTable.UpdatePendingFabricWithOperationalKeystore(2, noc, ByteSpan{}, FabricTable::AdvertiseIdentity::No));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterSecondAdd);

        // Validate iterator sees the pending data
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            bool saw2          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 11);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.ShouldAdvertiseIdentity());
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1000);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    NL_TEST_ASSERT(inSuite, !iterFabricInfo.ShouldAdvertiseIdentity());
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), (numStorageAfterSecondAdd - 1)); // ICAC got deleted

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == fabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(fabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(fabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Validate iterator sees the committed update
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            bool saw2          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 11);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1000);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }

        // Next fabric index has stayed the same.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }
    }

    size_t numStorageAfterUpdate = storage.GetNumKeys();

    // Sequence 4: Rename fabric index 2, applies immediately when nothing pending
    {
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SetFabricLabel(2, CharSpan("roboto")));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), numStorageAfterUpdate); // Number of keys unchanged

        // Validate basic contents
        {
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 1000);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 44);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().data_equal(CharSpan{ "roboto", strlen("roboto") }));
            }
        }

        // Next fabric index has stayed the same.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }
    }

    // Sequence 5: Remove FabricIndex 1 (FabricId 11, NodeId 55), make sure FabricIndex 2 (FabricId 44, NodeId 1000) still exists
    {
        // Remove the fabric: no commit needed
        {
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.Delete(1));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

            NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), (numStorageAfterUpdate - 3)); // Deleted NOC, RCAC, Metadata
        }

        // Next fabric index has stayed the same.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }

        // Validate contents of Fabric Index 2 is still OK
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 1000);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 44);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().data_equal(CharSpan{ "roboto", strlen("roboto") }));

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(2, rootPublicKeyOfFabric));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            uint8_t nocBuf[Credentials::kMaxCHIPCertLength];
            MutableByteSpan nocSpan{ nocBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchNOCCert(2, nocSpan));

            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(nocSpan, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey nocPubKey(certificates.GetCertSet()[0].mPublicKey);

            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(2, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Validate iterator only sees the remaining fabric
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            bool saw2          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1000);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == false);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }
    }
}

void TestAddMultipleSameRootDifferentFabricId(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    uint8_t rcac1Buf[kMaxCHIPCertLength];
    MutableByteSpan rcac1Span{ rcac1Buf };

    // First scope: add FabricID 1111, node ID 55
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        // Keep a copy for second scope check
        CopySpanToMutableSpan(rcac, rcac1Span);

        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterFirstAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

    // Second scope: add FabricID 2222, node ID 66, same root as first
    {
        FabricId fabricId = 2222;
        NodeId nodeId     = 66;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac2 = fabricCertAuthority.GetRcac();
        NL_TEST_ASSERT(inSuite, rcac2.data_equal(rcac1Span));

        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac2));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterSecondAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterSecondAdd == (numStorageKeysAfterFirstAdd + 5)); // Add 3 certs, 1 metadata, 1 opkey
}

void TestAddMultipleSameFabricIdDifferentRoot(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority1;
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority2;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority1.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, fabricCertAuthority2.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    uint8_t rcac1Buf[kMaxCHIPCertLength];
    MutableByteSpan rcac1Span{ rcac1Buf };

    // First scope: add FabricID 1111, node ID 55
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority1.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority1.GetRcac();
        // Keep a copy for second scope check
        CopySpanToMutableSpan(rcac, rcac1Span);

        ByteSpan icac = fabricCertAuthority1.GetIcac();
        ByteSpan noc  = fabricCertAuthority1.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterFirstAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

    // Second scope: add FabricID 1111, node ID 66, different root from first
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 66;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority2.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac2 = fabricCertAuthority2.GetRcac();
        NL_TEST_ASSERT(inSuite, !rcac2.data_equal(rcac1Span));

        ByteSpan icac = fabricCertAuthority2.GetIcac();
        ByteSpan noc  = fabricCertAuthority2.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac2));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterSecondAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterSecondAdd == (numStorageKeysAfterFirstAdd + 5)); // Add 3 certs, 1 metadata, 1 opkey
}

void TestPersistence(nlTestSuite * inSuite, void * inContext)
{
    /**
     *
     * - Create an outer scope with storage delegate
     *   - Keep buffer slots for the operational public keys of the 2 fabrics added in the next scope
     *
     * - Create a new scope with a ScopedFabricTable
     *   - Add 2 fabrics, fully committed, using OperationalKeystore-based storage (e.g. CSR for opkey)
     *   - Make sure to save public keys in other scope for next step
     *
     * - Create a new scope with a ScopedFabricTable
     *   - Validate that after init, it has 2 fabrics and the 2 fabrics match fabric indices expected,
     *     and that the fabric tables are usable, and that NOC can be extracted for each, and that
     *     its public key matches expectation, and that they match the public keys stored in outer scope
     *     and verify you can sign and verify messages with the opkey
     *
     */

    Crypto::P256PublicKey fIdx1PublicKey;
    Crypto::P256PublicKey fIdx2PublicKey;

    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;

    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // First scope: add 2 fabrics with same root: (1111, 2222), commit them, keep track of public keys
    {
        // Initialize a FabricTable
        ScopedFabricTable fabricTableHolder;
        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

        // Add Fabric 1111 Node Id 55
        {
            FabricId fabricId = 1111;
            NodeId nodeId     = 55;

            uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
            MutableByteSpan csrSpan{ csrBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
            ByteSpan rcac = fabricCertAuthority.GetRcac();
            ByteSpan icac = fabricCertAuthority.GetIcac();
            ByteSpan noc  = fabricCertAuthority.GetNoc();

            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
            NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

            // Validate contents
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), fIdx1PublicKey));

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }
        }

        // Add Fabric 2222 Node Id 66, no ICAC
        {
            FabricId fabricId = 2222;
            NodeId nodeId     = 66;

            uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
            MutableByteSpan csrSpan{ csrBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
            ByteSpan rcac = fabricCertAuthority.GetRcac();
            ByteSpan noc  = fabricCertAuthority.GetNoc();

            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
            NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

            // Validate contents
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), fIdx2PublicKey));

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx2PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }
        }

        NL_TEST_ASSERT(inSuite, fabricTable.FabricCount() == 2);

        // Verify we can now see 2 fabrics with the iterator
        {
            size_t numFabricsIterated = 0;
            bool saw1                 = false;
            bool saw2                 = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 1111);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 66);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 2222);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }

        // Next fabric index should now be 3, since we added 1 and 2 above.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }
    }

    // Global: Last known good time + fabric index = 2
    // Fabric 1111: Metadata, 1 opkey, RCAC/ICAC/NOC = 5
    // Fabric 2222: Metadata, 1 opkey, RCAC/NOC = 4
    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == (2 + 5 + 4));

    // Second scope: Validate that a fresh FabricTable loads the previously committed fabrics on Init.
    {
        // Initialize a FabricTable
        ScopedFabricTable fabricTableHolder;
        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);

        // Verify we can see 2 fabrics with the iterator
        {
            size_t numFabricsIterated = 0;
            bool saw1                 = false;
            bool saw2                 = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 1111);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 66);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 2222);
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 2);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == true);
        }

        // Validate contents of Fabric 2222
        {
            uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
            MutableByteSpan rcacSpan{ rcacBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootCert(2, rcacSpan));

            const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcacSpan, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(2, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(2, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx2PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }
        }

        // Validate contents of Fabric 1111
        {
            uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
            MutableByteSpan rcacSpan{ rcacBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootCert(1, rcacSpan));

            const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcacSpan, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(1, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(1, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }

            // Validate that signing with Fabric index 2 fails to verify with fabric index 1
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(2, ByteSpan{ message }, sig));
                NL_TEST_ASSERT(inSuite,
                               fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig) ==
                                   CHIP_ERROR_INVALID_SIGNATURE);
            }
        }

        // Validate that next fabric index is still 3;
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 3);
        }
    }
}

void TestAddNocFailSafe(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabric11CertAuthority;
    Credentials::TestOnlyLocalCertificateAuthority fabric44CertAuthority;

    chip::TestPersistentStorageDelegate storage;

    NL_TEST_ASSERT(inSuite, fabric11CertAuthority.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, fabric44CertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    size_t numFabricsIterated = 0;

    size_t numStorageKeysAtStart = storage.GetNumKeys();

    // Sequence 1: Add node ID 55 on fabric 11, see that pending works, and that revert works
    {
        FabricId fabricId = 11;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric11CertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric11CertAuthority.GetRcac();
        ByteSpan noc  = fabric11CertAuthority.GetNoc();

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;

        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 1);
        }

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAtStart); // Nothing yet

        // Validate iterator sees pending
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == nodeId);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == fabricId);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }

        // Revert, should see nothing yet
        fabricTable.RevertPendingFabricData();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

        // No started except fabric index metadata
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == (numStorageKeysAtStart + 1));

        // Validate iterator sees nothing
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 0);
            NL_TEST_ASSERT(inSuite, saw1 == false);
        }

        // Validate next fabric index has not changed.
        {
            FabricIndex nextFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT(inSuite, fabricTable.PeekFabricIndexForNextAddition(nextFabricIndex) == CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, nextFabricIndex, 1);
        }
    }

    size_t numStorageAfterRevert = storage.GetNumKeys();

    // Sequence 2: Add node ID 999 on fabric 44, using operational keystore and ICAC --> Yield fabricIndex 1
    {
        FabricId fabricId = 44;
        NodeId nodeId     = 999;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan icac = fabric44CertAuthority.GetIcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);
        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterRevert);

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(),
                              (numStorageAfterRevert + 5)); // 3 opcerts + fabric metadata + 1 operational key

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == newFabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Verify we can now see the fabric with the iterator
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }

    size_t numStorageAfterAdd = storage.GetNumKeys();

    // Sequence 3: Do a RevertPendingFabricData() again, see that it doesn't affect existing fabric

    {
        // Revert, should should look like a no-op
        fabricTable.RevertPendingFabricData();

        // No change of storage
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterAdd);

        // Verify we can still see the fabric with the iterator
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }
}

void TestUpdateNocFailSafe(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabric11CertAuthority;
    Credentials::TestOnlyLocalCertificateAuthority fabric44CertAuthority;

    chip::TestPersistentStorageDelegate storage;

    storage.SetLoggingLevel(chip::TestPersistentStorageDelegate::LoggingLevel::kLogMutation);

    NL_TEST_ASSERT(inSuite, fabric11CertAuthority.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, fabric44CertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    size_t numFabricsIterated = 0;

    size_t numStorageKeysAtStart = storage.GetNumKeys();

    // Sequence 1: Add node ID 999 on fabric 44, using operational keystore and ICAC --> Yield fabricIndex 1
    {
        FabricId fabricId = 44;
        NodeId nodeId     = 999;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan icac = fabric44CertAuthority.GetIcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);
        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAtStart);

        // Commit, now storage should have keys
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(),
                              (numStorageKeysAtStart + 6)); // 3 opcerts + fabric metadata + 1 operational key + LKGT + fabric index

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == newFabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == nodeId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == fabricId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Verify we can now see the fabric with the iterator
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }

    size_t numStorageAfterAdd = storage.GetNumKeys();

    // Sequence 2: Do an Update to NodeId 1000, with no ICAC, but revert it
    {
        FabricId fabricId       = 44;
        NodeId nodeId           = 1000;
        FabricIndex fabricIndex = 1;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };

        // Make sure to tag fabric index to pending opkey: otherwise the UpdateNOC fails
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AllocatePendingOperationalKey(chip::MakeOptional(static_cast<FabricIndex>(1)), csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.UpdatePendingFabricWithOperationalKeystore(1, noc, ByteSpan{}));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterAdd);

        // Validate iterator sees the pending data
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1000);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.ShouldAdvertiseIdentity());
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }

        // Revert, should see Node ID 999 again
        fabricTable.RevertPendingFabricData();
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), numStorageAfterAdd);

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == fabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 999);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 44);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(fabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            uint8_t nocBuf[Credentials::kMaxCHIPCertLength];
            MutableByteSpan nocSpan{ nocBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchNOCCert(1, nocSpan));

            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(nocSpan, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey nocPubKey(certificates.GetCertSet()[0].mPublicKey);

            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(fabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Validate iterator sees the previous fabric
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 999);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }

    // Sequence 3: Do an Update to NodeId 1001, with no ICAC, but commit it
    {
        FabricId fabricId       = 44;
        NodeId nodeId           = 1001;
        FabricIndex fabricIndex = 1;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };

        // Make sure to tag fabric index to pending opkey: otherwise the UpdateNOC fails
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AllocatePendingOperationalKey(chip::MakeOptional(static_cast<FabricIndex>(1)), csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabric44CertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabric44CertAuthority.GetRcac();
        ByteSpan noc  = fabric44CertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.UpdatePendingFabricWithOperationalKeystore(1, noc, ByteSpan{}));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // No storage yet
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageAfterAdd);

        // Validate iterator sees the pending data
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1001);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.ShouldAdvertiseIdentity());
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }

        // Commit, should see Node ID 1001, and 1 less cert in the storage
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_EQUALS(inSuite, storage.GetNumKeys(), numStorageAfterAdd - 1);

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == fabricIndex);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 1001);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 44);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(fabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }

        // Validate that fabric has the correct operational key by verifying a signature
        {
            Crypto::P256PublicKey nocPubKey;
            NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), nocPubKey));

            Crypto::P256ECDSASignature sig;
            uint8_t message[] = { 'm', 's', 'g' };

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(fabricIndex, ByteSpan{ message }, sig));
            NL_TEST_ASSERT_SUCCESS(inSuite, nocPubKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
        }

        // Validate iterator sees the updated fabric
        {
            numFabricsIterated = 0;
            bool saw1          = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 1001);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 44);
                    saw1 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
        }
    }
}

void TestAddRootCertFailSafe(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabric11CertAuthority;

    chip::TestPersistentStorageDelegate storage;

    NL_TEST_ASSERT(inSuite, fabric11CertAuthority.Init().IsSuccess());

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    // Add a root cert, see that pending works, and that revert works
    {
        ByteSpan rcac = fabric11CertAuthority.GetRcac();

        uint8_t rcacBuf[Credentials::kMaxCHIPCertLength];
        {
            // No pending root cert yet.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan) == CHIP_ERROR_NOT_FOUND);
        }

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        {
            // Now have a pending root cert.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan));
            NL_TEST_ASSERT(inSuite, fetchedSpan.data_equal(rcac));
        }

        // Revert
        fabricTable.RevertPendingFabricData();

        {
            // No pending root cert anymore.
            MutableByteSpan fetchedSpan{ rcacBuf };
            NL_TEST_ASSERT(inSuite, fabricTable.FetchPendingNonFabricAssociatedRootCert(fetchedSpan) == CHIP_ERROR_NOT_FOUND);
        }
    }
}

void TestSequenceErrors(nlTestSuite * inSuite, void * inContext)
{
    // TODO: Write test
}

void TestFabricLabelChange(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    // First scope: add FabricID 1111, node ID 55
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
    size_t numStorageKeysAfterFirstAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

    // Second scope: set FabricLabel to "acme fabric", make sure it cannot be reverted
    {
        // Fabric label starts unset from prior scope
        CharSpan fabricLabel = CharSpan::fromCharString("placeholder");

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.size() == 0);

        // Set a valid name
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SetFabricLabel(1, CharSpan::fromCharString("acme fabric")));
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal(CharSpan::fromCharString("acme fabric")) == true);

        // Revert pending fabric data. Should not revert name since nothing pending.
        fabricTable.RevertPendingFabricData();

        fabricLabel = CharSpan::fromCharString("placeholder");
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal(CharSpan::fromCharString("acme fabric")) == true);

        // Verify we fail to set too large a label (> kFabricLabelMaxLengthInBytes)
        CharSpan fabricLabelTooBig = CharSpan::fromCharString("012345678901234567890123456789123456");
        NL_TEST_ASSERT(inSuite, fabricLabelTooBig.size() > chip::kFabricLabelMaxLengthInBytes);

        NL_TEST_ASSERT(inSuite, fabricTable.SetFabricLabel(1, fabricLabelTooBig) == CHIP_ERROR_INVALID_ARGUMENT);

        fabricLabel = CharSpan::fromCharString("placeholder");
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal(CharSpan::fromCharString("acme fabric")) == true);
    }

    // Third scope: set fabric label after an update, it sticks, but then goes back after revert
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 66; // Update node ID from 55 to 66

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AllocatePendingOperationalKey(chip::MakeOptional(static_cast<FabricIndex>(1)), csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.UpdatePendingFabricWithOperationalKeystore(1, noc, icac));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // Validate contents prior to change/revert
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);

        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);

            CharSpan fabricLabel = fabricInfo->GetFabricLabel();
            NL_TEST_ASSERT(inSuite, fabricLabel.data_equal(CharSpan::fromCharString("acme fabric")) == true);
        }

        // Update fabric label
        CharSpan fabricLabel = CharSpan::fromCharString("placeholder");
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SetFabricLabel(1, CharSpan::fromCharString("roboto fabric")));

        fabricLabel = CharSpan::fromCharString("placeholder");
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal(CharSpan::fromCharString("roboto fabric")) == true);

        // Revert pending fabric data. Should revert name to "acme fabric"
        fabricTable.RevertPendingFabricData();

        fabricLabel = CharSpan::fromCharString("placeholder");
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.GetFabricLabel(1, fabricLabel));
        NL_TEST_ASSERT(inSuite, fabricLabel.data_equal(CharSpan::fromCharString("acme fabric")) == true);
    }
}

void TestCompressedFabricId(nlTestSuite * inSuite, void * inContext)
{
    // TODO: Write test
}

void TestFabricLookup(nlTestSuite * inSuite, void * inContext)
{
    // Initialize a fabric table.
    chip::TestPersistentStorageDelegate testStorage;
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite,
                   LoadTestFabric_Node02_01(inSuite, fabricTable, /* doCommit = */ true, FabricTable::AdvertiseIdentity::No) ==
                       CHIP_NO_ERROR);

    // Attempt lookup of the Root01 fabric.
    {
        Crypto::P256PublicKey key;
        NL_TEST_ASSERT(inSuite, key.Length() >= TestCerts::sTestCert_Root01_PublicKey.size());
        if (key.Length() < TestCerts::sTestCert_Root01_PublicKey.size())
        {
            return;
        }
        memcpy(key.Bytes(), TestCerts::sTestCert_Root01_PublicKey.data(), TestCerts::sTestCert_Root01_PublicKey.size());
        auto fabricInfo = fabricTable.FindFabric(key, 0xFAB000000000001D);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo == nullptr)
        {
            return;
        }
        NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
        NL_TEST_ASSERT(inSuite, fabricInfo->ShouldAdvertiseIdentity());
    }

    // Attempt lookup of the Root02 fabric.
    {
        Crypto::P256PublicKey key;
        NL_TEST_ASSERT(inSuite, key.Length() >= TestCerts::sTestCert_Root02_PublicKey.size());
        if (key.Length() < TestCerts::sTestCert_Root02_PublicKey.size())
        {
            return;
        }
        memcpy(key.Bytes(), TestCerts::sTestCert_Root02_PublicKey.data(), TestCerts::sTestCert_Root02_PublicKey.size());
        auto fabricInfo = fabricTable.FindFabric(key, 0xFAB000000000001D);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo == nullptr)
        {
            return;
        }
        NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
        NL_TEST_ASSERT(inSuite, !fabricInfo->ShouldAdvertiseIdentity());
    }

    // Attempt lookup of FabricIndex 0 --> should always fail.
    {
        NL_TEST_ASSERT(inSuite, fabricTable.FindFabricWithIndex(0) == nullptr);
    }
}

void TestFetchCATs(nlTestSuite * inSuite, void * inContext)
{
    // Initialize a fabric table.
    chip::TestPersistentStorageDelegate testStorage;
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&testStorage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node01_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);
    NL_TEST_ASSERT(inSuite, LoadTestFabric_Node02_01(inSuite, fabricTable, /* doCommit = */ true) == CHIP_NO_ERROR);

    // Attempt Fetching fabric index 1 CATs and verify contents.
    {
        CATValues cats;
        NL_TEST_ASSERT(inSuite, fabricTable.FetchCATs(1, cats) == CHIP_NO_ERROR);
        // Test fabric NOCs don't contain any CATs.
        NL_TEST_ASSERT(inSuite, cats == kUndefinedCATs);
    }

    // Attempt Fetching fabric index 2 CATs and verify contents.
    {
        CATValues cats;
        NL_TEST_ASSERT(inSuite, fabricTable.FetchCATs(2, cats) == CHIP_NO_ERROR);
        // Test fabric NOCs don't contain any CATs.
        NL_TEST_ASSERT(inSuite, cats == kUndefinedCATs);
    }

    // TODO(#20335): Add test cases for NOCs that actually embed CATs
}

// Validate that adding the same fabric twice fails (same root, same FabricId)
void TestAddNocRootCollision(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    // First scope: add FabricID 1111, node ID 55
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex,
                                                                                      FabricTable::AdvertiseIdentity::No));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, !fabricInfo->ShouldAdvertiseIdentity());

            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }
    }
    size_t numStorageKeysAfterFirstAdd = storage.GetNumKeys();
    NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

    // Second scope: add FabricID 1111, node ID 55 *again* --> Collision of Root/FabricID with existing
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT(inSuite,
                       fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex) ==
                           CHIP_ERROR_FABRIC_EXISTS);
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        CHIP_ERROR err = fabricTable.CommitPendingFabricData();
        printf("err = %" CHIP_ERROR_FORMAT "\n", err.Format());
        NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE);

        // Validate contents of Fabric index 1 still valid
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(1, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }
    }

    // Ensure no new persisted keys after failed colliding add
    NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAfterFirstAdd);

    // Third scope: add FabricID 2222, node ID 55 --> Not colliding, should work. The failing commit above]
    // should have been enough of a revert that this scope succeeds without any additional revert.
    {
        FabricId fabricId = 2222;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->ShouldAdvertiseIdentity());

            Credentials::ChipCertificateSet certificates;
            NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
            Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

            Crypto::P256PublicKey rootPublicKeyOfFabric;
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
            NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
        }
    }
    size_t numStorageKeysAfterSecondAdd = storage.GetNumKeys();

    NL_TEST_ASSERT(inSuite, numStorageKeysAfterSecondAdd == (numStorageKeysAfterFirstAdd + 5)); // Metadata, 3 certs, 1 opkey
}

void TestInvalidChaining(nlTestSuite * inSuite, void * inContext)
{
    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;
    Credentials::TestOnlyLocalCertificateAuthority differentCertAuthority;

    chip::TestPersistentStorageDelegate storage;
    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());
    NL_TEST_ASSERT(inSuite, differentCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    // Initialize a fabric table.
    ScopedFabricTable fabricTableHolder;
    NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
    FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

    NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

    // Try to add fabric with either the NOC not chaining properly, or ICAC not chaining properly, fail,
    // then succeed with proper chaining
    {
        FabricId fabricId = 1111;
        NodeId nodeId     = 55;

        uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
        MutableByteSpan csrSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

        // Generate same cert chain from two different roots
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               differentCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());

        ByteSpan rcac = fabricCertAuthority.GetRcac();
        ByteSpan icac = fabricCertAuthority.GetIcac();
        ByteSpan noc  = fabricCertAuthority.GetNoc();

        ByteSpan otherIcac = differentCertAuthority.GetIcac();
        ByteSpan otherNoc  = differentCertAuthority.GetNoc();

        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));

        // Add with NOC not chaining to ICAC: fail
        {
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            CHIP_ERROR err = fabricTable.AddNewPendingFabricWithOperationalKeystore(otherNoc, icac, kVendorId, &newFabricIndex);
            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        }

        // Add with ICAC not chaining to root: fail
        {
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            CHIP_ERROR err = fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, otherIcac, kVendorId, &newFabricIndex);
            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        }

        // Add with NOC and ICAC chaining together, but not to root: fail
        {
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            CHIP_ERROR err =
                fabricTable.AddNewPendingFabricWithOperationalKeystore(otherNoc, otherIcac, kVendorId, &newFabricIndex);
            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        }

        // Revert state, start tests without ICAC
        fabricTable.RevertPendingFabricData();

        // Generate same cert chain from two different roots

        csrSpan = MutableByteSpan{ csrBuf };
        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
        NL_TEST_ASSERT_SUCCESS(
            inSuite, differentCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());

        rcac = fabricCertAuthority.GetRcac();
        noc  = fabricCertAuthority.GetNoc();

        otherNoc = differentCertAuthority.GetNoc();

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));

        // Add with NOC not chaining to RCAC: fail
        {
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            CHIP_ERROR err =
                fabricTable.AddNewPendingFabricWithOperationalKeystore(otherNoc, ByteSpan{}, kVendorId, &newFabricIndex);
            NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
        }

        // Add properly now
        FabricIndex newFabricIndex = kUndefinedFabricIndex;
        NL_TEST_ASSERT_SUCCESS(inSuite,
                               fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex));
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
        NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

        // Validate contents
        const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
        NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
        if (fabricInfo != nullptr)
        {
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
            NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);
        }
    }
}

void TestEphemeralKeys(nlTestSuite * inSuite, void * inContext)
{
    // Initialize a fabric table with operational keystore
    {
        chip::TestPersistentStorageDelegate storage;

        // Initialize a FabricTable
        ScopedFabricTable fabricTableHolder;
        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        Crypto::P256ECDSASignature sig;
        uint8_t message[] = { 'm', 's', 'g' };

        Crypto::P256Keypair * ephemeralKeypair = fabricTable.AllocateEphemeralKeypairForCASE();
        NL_TEST_ASSERT(inSuite, ephemeralKeypair != nullptr);
        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->Initialize(Crypto::ECPKeyTarget::ECDSA));

        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->ECDSA_sign_msg(message, sizeof(message), sig));
        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->Pubkey().ECDSA_validate_msg_signature(message, sizeof(message), sig));

        fabricTable.ReleaseEphemeralKeypair(ephemeralKeypair);
    }

    // Use a fabric table without an operational keystore: should still work
    {
        chip::TestPersistentStorageDelegate storage;

        chip::Credentials::PersistentStorageOpCertStore opCertStore;
        NL_TEST_ASSERT_SUCCESS(inSuite, opCertStore.Init(&storage));

        FabricTable fabricTable;
        FabricTable::InitParams initParams;
        initParams.storage     = &storage;
        initParams.opCertStore = &opCertStore;

        NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.Init(initParams));

        Crypto::P256ECDSASignature sig;
        uint8_t message[] = { 'm', 's', 'g' };

        Crypto::P256Keypair * ephemeralKeypair = fabricTable.AllocateEphemeralKeypairForCASE();
        NL_TEST_ASSERT(inSuite, ephemeralKeypair != nullptr);
        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->Initialize(Crypto::ECPKeyTarget::ECDSA));

        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->ECDSA_sign_msg(message, sizeof(message), sig));
        NL_TEST_ASSERT_SUCCESS(inSuite, ephemeralKeypair->Pubkey().ECDSA_validate_msg_signature(message, sizeof(message), sig));

        fabricTable.ReleaseEphemeralKeypair(ephemeralKeypair);

        fabricTable.Shutdown();
        opCertStore.Finish();
    }
}

void TestCommitMarker(nlTestSuite * inSuite, void * inContext)
{
    Crypto::P256PublicKey fIdx1PublicKey;
    Crypto::P256PublicKey fIdx2PublicKey;

    Credentials::TestOnlyLocalCertificateAuthority fabricCertAuthority;

    chip::TestPersistentStorageDelegate storage;

    // Log verbosity on this test helps debug significantly
    storage.SetLoggingLevel(chip::TestPersistentStorageDelegate::LoggingLevel::kLogMutationAndReads);

    NL_TEST_ASSERT(inSuite, fabricCertAuthority.Init().IsSuccess());

    constexpr uint16_t kVendorId = 0xFFF1u;

    size_t numStorageKeysAfterFirstAdd = 0;

    // First scope: add 2 fabrics with same root:
    //   - FabricID 1111, Node ID 55
    //   - FabricID 2222, Node ID 66
    //      - Abort commit on second fabric
    {
        // Initialize a fabric table
        ScopedFabricTable fabricTableHolder;
        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == kUndefinedFabricIndex);
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);

        // Add Fabric 1111 Node Id 55
        {
            FabricId fabricId = 1111;
            NodeId nodeId     = 55;

            uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
            MutableByteSpan csrSpan{ csrBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricCertAuthority.SetIncludeIcac(true).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
            ByteSpan rcac = fabricCertAuthority.GetRcac();
            ByteSpan icac = fabricCertAuthority.GetIcac();
            ByteSpan noc  = fabricCertAuthority.GetNoc();

            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 0);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT_SUCCESS(inSuite,
                                   fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, icac, kVendorId, &newFabricIndex));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
            NL_TEST_ASSERT(inSuite, newFabricIndex == 1);

            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.CommitPendingFabricData());

            // Validate contents
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(1);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 1);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 55);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 1111);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Validate that fabric has the correct operational key by verifying a signature
            {
                Crypto::P256ECDSASignature sig;
                uint8_t message[] = { 'm', 's', 'g' };

                NL_TEST_ASSERT_SUCCESS(inSuite, VerifyCertificateSigningRequest(csrSpan.data(), csrSpan.size(), fIdx1PublicKey));

                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.SignWithOpKeypair(newFabricIndex, ByteSpan{ message }, sig));
                NL_TEST_ASSERT_SUCCESS(inSuite, fIdx1PublicKey.ECDSA_validate_msg_signature(&message[0], sizeof(message), sig));
            }
        }
        numStorageKeysAfterFirstAdd = storage.GetNumKeys();

        NL_TEST_ASSERT(inSuite, numStorageKeysAfterFirstAdd == 7); // Metadata, index, 3 certs, 1 opkey, last known good time

        // The following test requires test methods not available on all builds.
        // TODO: Debug why some CI jobs don't set it properly.
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST

        // Add Fabric 2222 Node Id 66, no ICAC *** AND ABORT COMMIT ***
        {
            FabricId fabricId = 2222;
            NodeId nodeId     = 66;

            uint8_t csrBuf[chip::Crypto::kMIN_CSR_Buffer_Size];
            MutableByteSpan csrSpan{ csrBuf };
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AllocatePendingOperationalKey(chip::NullOptional, csrSpan));

            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricCertAuthority.SetIncludeIcac(false).GenerateNocChain(fabricId, nodeId, csrSpan).GetStatus());
            ByteSpan rcac = fabricCertAuthority.GetRcac();
            ByteSpan noc  = fabricCertAuthority.GetNoc();

            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);
            NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.AddNewPendingTrustedRootCert(rcac));
            FabricIndex newFabricIndex = kUndefinedFabricIndex;
            NL_TEST_ASSERT_SUCCESS(
                inSuite, fabricTable.AddNewPendingFabricWithOperationalKeystore(noc, ByteSpan{}, kVendorId, &newFabricIndex));
            NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 2);
            NL_TEST_ASSERT(inSuite, newFabricIndex == 2);

            // Validate contents of pending
            const auto * fabricInfo = fabricTable.FindFabricWithIndex(2);
            NL_TEST_ASSERT(inSuite, fabricInfo != nullptr);
            if (fabricInfo != nullptr)
            {
                Credentials::ChipCertificateSet certificates;
                NL_TEST_ASSERT_SUCCESS(inSuite, certificates.Init(1));
                NL_TEST_ASSERT_SUCCESS(inSuite,
                                       certificates.LoadCert(rcac, BitFlags<CertDecodeFlags>(CertDecodeFlags::kIsTrustAnchor)));
                Crypto::P256PublicKey rcacPublicKey(certificates.GetCertSet()[0].mPublicKey);

                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricIndex() == 2);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetNodeId() == 66);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricId() == 2222);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetVendorId() == kVendorId);
                NL_TEST_ASSERT(inSuite, fabricInfo->GetFabricLabel().size() == 0);

                Crypto::P256PublicKey rootPublicKeyOfFabric;
                NL_TEST_ASSERT_SUCCESS(inSuite, fabricTable.FetchRootPubkey(newFabricIndex, rootPublicKeyOfFabric));
                NL_TEST_ASSERT(inSuite, rootPublicKeyOfFabric.Matches(rcacPublicKey));
            }

            // Make sure no additional storage yet
            NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAfterFirstAdd);

            // --> FORCE AN ERROR ON COMMIT that will BYPASS commit clean-up (similar to reboot during commit)
            fabricTable.SetForceAbortCommitForTest(true);
            NL_TEST_ASSERT(inSuite, fabricTable.CommitPendingFabricData() == CHIP_ERROR_INTERNAL);

            // Check that there are more keys now, partially committed: at least a Commit Marker (+1)
            // and some more keys from the aborted process.
            NL_TEST_ASSERT(inSuite, storage.GetNumKeys() > (numStorageKeysAfterFirstAdd + 1));
        }
#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST
    }

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    {
        storage.DumpKeys();

        // Initialize a FabricTable again. Make sure it succeeds in initing.
        ScopedFabricTable fabricTableHolder;

        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() > (numStorageKeysAfterFirstAdd + 1));

        NL_TEST_ASSERT(inSuite, fabricTableHolder.Init(&storage) == CHIP_NO_ERROR);
        FabricTable & fabricTable = fabricTableHolder.GetFabricTable();

        // Make sure that after init, the fabricTable has only 1 fabric
        NL_TEST_ASSERT_EQUALS(inSuite, fabricTable.FabricCount(), 1);

        // Make sure it caught the last partially committed fabric
        NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == 2);

        // Second read must return kUndefinedFabricIndex
        NL_TEST_ASSERT(inSuite, fabricTable.GetDeletedFabricFromCommitMarker() == kUndefinedFabricIndex);

        {
            // Here we would do other clean-ups (e.g. see Server.cpp that uses the above) and then
            // clear the commit marker after.
            fabricTable.ClearCommitMarker();
        }

        // Make sure that all other pending storage got deleted
        NL_TEST_ASSERT(inSuite, storage.GetNumKeys() == numStorageKeysAfterFirstAdd);

        // Verify we can only see 1 fabric with the iterator
        {
            size_t numFabricsIterated = 0;
            bool saw1                 = false;
            bool saw2                 = false;
            for (const auto & iterFabricInfo : fabricTable)
            {
                ++numFabricsIterated;
                if (iterFabricInfo.GetFabricIndex() == 1)
                {
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetNodeId() == 55);
                    NL_TEST_ASSERT(inSuite, iterFabricInfo.GetFabricId() == 1111);
                    saw1 = true;
                }
                if (iterFabricInfo.GetFabricIndex() == 2)
                {
                    saw2 = true;
                }
            }

            NL_TEST_ASSERT(inSuite, numFabricsIterated == 1);
            NL_TEST_ASSERT(inSuite, saw1 == true);
            NL_TEST_ASSERT(inSuite, saw2 == false);
        }
    }
#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST
}

// Test Suite

/**
 *  Test Suite that lists all the test functions.
 */
// clang-format off
static const nlTest sTests[] =
{
    NL_TEST_DEF("Last Known Good Time Init", TestLastKnownGoodTimeInit),
    NL_TEST_DEF("Update Last Known Good Time", TestUpdateLastKnownGoodTime),
    NL_TEST_DEF("Set Last Known Good Time", TestSetLastKnownGoodTime),
    NL_TEST_DEF("Test basic AddNOC flow", TestBasicAddNocUpdateNocFlow),
    NL_TEST_DEF("Test adding multiple fabrics that chain to same root, different fabric ID", TestAddMultipleSameRootDifferentFabricId),
    NL_TEST_DEF("Test adding multiple fabrics that chain to different roots, same fabric ID", TestAddMultipleSameFabricIdDifferentRoot),
    NL_TEST_DEF("Validate fabrics are loaded from persistence at FabricTable::init", TestPersistence),
    NL_TEST_DEF("Test fail-safe handling during AddNOC", TestAddNocFailSafe),
    NL_TEST_DEF("Test fail-safe handling during UpdateNoc", TestUpdateNocFailSafe),
    NL_TEST_DEF("Test fail-safe handling for root cert", TestAddRootCertFailSafe),
    NL_TEST_DEF("Test interlock sequencing errors", TestSequenceErrors),
    NL_TEST_DEF("Test fabric label changes", TestFabricLabelChange),
    NL_TEST_DEF("Test compressed fabric ID is properly generated", TestCompressedFabricId),
    NL_TEST_DEF("Test fabric lookup by <root public key, fabric ID>", TestFabricLookup),
    NL_TEST_DEF("Test Fetching CATs", TestFetchCATs),
    NL_TEST_DEF("Test AddNOC root collision", TestAddNocRootCollision),
    NL_TEST_DEF("Test invalid chaining in AddNOC and UpdateNOC", TestInvalidChaining),
    NL_TEST_DEF("Test ephemeral keys allocation", TestEphemeralKeys),
    NL_TEST_DEF("Test proper detection of Commit Marker on init", TestCommitMarker),
    NL_TEST_DEF("Test colliding fabrics in the fabric table", TestCollidingFabrics),

    NL_TEST_SENTINEL()
};

// clang-format on

int TestFabricTable_Setup(void * inContext);
int TestFabricTable_Teardown(void * inContext);

// clang-format off
static nlTestSuite sSuite =
{
    "Test-CHIP-FabricTable",
    &sTests[0],
    TestFabricTable_Setup,
    TestFabricTable_Teardown,
};
// clang-format on

/**
 *  Set up the test suite.
 */
int TestFabricTable_Setup(void * inContext)
{
    DeviceLayer::SetConfigurationMgr(&DeviceLayer::ConfigurationManagerImpl::GetDefaultInstance());
    return chip::Platform::MemoryInit() == CHIP_NO_ERROR ? SUCCESS : FAILURE;
}

/**
 *  Tear down the test suite.
 */
int TestFabricTable_Teardown(void * inContext)
{
    chip::Platform::MemoryShutdown();
    return SUCCESS;
}

} // namespace

/**
 *  Main
 */
int TestFabricTable()
{
    // Run test suit against one context
    nlTestRunner(&sSuite, nullptr);

    return (nlTestRunnerStats(&sSuite));
}

CHIP_REGISTER_TEST_SUITE(TestFabricTable)
