/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *
 *    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.
 */

#pragma once

#include <app/AppBuildConfig.h>

#include <access/AccessControl.h>
#include <access/examples/ExampleAccessControlDelegate.h>
#include <app/CASEClientPool.h>
#include <app/CASESessionManager.h>
#include <app/DefaultAttributePersistenceProvider.h>
#include <app/FailSafeContext.h>
#include <app/OperationalSessionSetupPool.h>
#include <app/SimpleSubscriptionResumptionStorage.h>
#include <app/TestEventTriggerDelegate.h>
#include <app/server/AclStorage.h>
#include <app/server/AppDelegate.h>
#include <app/server/CommissioningWindowManager.h>
#include <app/server/DefaultAclStorage.h>
#include <credentials/CertificateValidityPolicy.h>
#include <credentials/FabricTable.h>
#include <credentials/GroupDataProvider.h>
#include <credentials/GroupDataProviderImpl.h>
#include <credentials/OperationalCertificateStore.h>
#include <credentials/PersistentStorageOpCertStore.h>
#include <crypto/DefaultSessionKeystore.h>
#include <crypto/OperationalKeystore.h>
#include <crypto/PersistentStorageOperationalKeystore.h>
#include <inet/InetConfig.h>
#include <lib/core/CHIPConfig.h>
#include <lib/support/SafeInt.h>
#include <messaging/ExchangeMgr.h>
#include <platform/KeyValueStoreManager.h>
#include <platform/KvsPersistentStorageDelegate.h>
#include <protocols/secure_channel/CASEServer.h>
#include <protocols/secure_channel/MessageCounterManager.h>
#include <protocols/secure_channel/PASESession.h>
#include <protocols/secure_channel/RendezvousParameters.h>
#include <protocols/secure_channel/UnsolicitedStatusHandler.h>
#if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
#include <protocols/secure_channel/SimpleSessionResumptionStorage.h>
#endif
#include <protocols/user_directed_commissioning/UserDirectedCommissioning.h>
#include <system/SystemClock.h>
#include <transport/SessionManager.h>
#include <transport/TransportMgr.h>
#include <transport/TransportMgrBase.h>
#if CONFIG_NETWORK_LAYER_BLE
#include <transport/raw/BLE.h>
#endif
#include <app/TimerDelegates.h>
#include <app/reporting/ReportSchedulerImpl.h>
#include <transport/raw/UDP.h>

#if CHIP_CONFIG_ENABLE_ICD_SERVER
#include <app/icd/ICDEventManager.h> // nogncheck
#include <app/icd/ICDManager.h>      // nogncheck
#endif

namespace chip {

constexpr size_t kMaxBlePendingPackets = 1;

//
// NOTE: Please do not alter the order of template specialization here as the logic
//       in the Server impl depends on this.
//
using ServerTransportMgr = chip::TransportMgr<chip::Transport::UDP
#if INET_CONFIG_ENABLE_IPV4
                                              ,
                                              chip::Transport::UDP
#endif
#if CONFIG_NETWORK_LAYER_BLE
                                              ,
                                              chip::Transport::BLE<kMaxBlePendingPackets>
#endif
                                              >;

struct ServerInitParams
{
    ServerInitParams() = default;

    // Not copyable
    ServerInitParams(const ServerInitParams &) = delete;
    ServerInitParams & operator=(const ServerInitParams &) = delete;

    // Application delegate to handle some commissioning lifecycle events
    AppDelegate * appDelegate = nullptr;
    // Port to use for Matter commissioning/operational traffic
    uint16_t operationalServicePort = CHIP_PORT;
    // Port to use for UDC if supported
    uint16_t userDirectedCommissioningPort = CHIP_UDC_PORT;
    // Interface on which to run daemon
    Inet::InterfaceId interfaceId = Inet::InterfaceId::Null();

    // Persistent storage delegate: MUST be injected. Used to maintain storage by much common code.
    // Must be initialized before being provided.
    PersistentStorageDelegate * persistentStorageDelegate = nullptr;
    // Session resumption storage: Optional. Support session resumption when provided.
    // Must be initialized before being provided.
    SessionResumptionStorage * sessionResumptionStorage = nullptr;
    // Session resumption storage: Optional. Support session resumption when provided.
    // Must be initialized before being provided.
    app::SubscriptionResumptionStorage * subscriptionResumptionStorage = nullptr;
    // Certificate validity policy: Optional. If none is injected, CHIPCert
    // enforces a default policy.
    Credentials::CertificateValidityPolicy * certificateValidityPolicy = nullptr;
    // Group data provider: MUST be injected. Used to maintain critical keys such as the Identity
    // Protection Key (IPK) for CASE. Must be initialized before being provided.
    Credentials::GroupDataProvider * groupDataProvider = nullptr;
    // Session keystore: MUST be injected. Used to derive and manage lifecycle of symmetric keys.
    Crypto::SessionKeystore * sessionKeystore = nullptr;
    // Access control delegate: MUST be injected. Used to look up access control rules. Must be
    // initialized before being provided.
    Access::AccessControl::Delegate * accessDelegate = nullptr;
    // ACL storage: MUST be injected. Used to store ACL entries in persistent storage. Must NOT
    // be initialized before being provided.
    app::AclStorage * aclStorage = nullptr;
    // Network native params can be injected depending on the
    // selected Endpoint implementation
    void * endpointNativeParams = nullptr;
    // Optional. Support test event triggers when provided. Must be initialized before being
    // provided.
    TestEventTriggerDelegate * testEventTriggerDelegate = nullptr;
    // Operational keystore with access to the operational keys: MUST be injected.
    Crypto::OperationalKeystore * operationalKeystore = nullptr;
    // Operational certificate store with access to the operational certs in persisted storage:
    // must not be null at timne of Server::Init().
    Credentials::OperationalCertificateStore * opCertStore = nullptr;
    // Required, if not provided, the Server::Init() WILL fail.
    app::reporting::ReportScheduler * reportScheduler = nullptr;
};

/**
 * Transitional version of ServerInitParams to assist SDK integrators in
 * transitioning to injecting product/platform-owned resources. This version
 * of `ServerInitParams` statically owns and initializes (via the
 * `InitializeStaticResourcesBeforeServerInit()` method) the persistent storage
 * delegate, the group data provider, and the access control delegate. This is to reduce
 * the amount of copied boilerplate in all the example initializations (e.g. AppTask.cpp,
 * main.cpp).
 *
 * This version SHOULD BE USED ONLY FOR THE IN-TREE EXAMPLES.
 *
 * ACTION ITEMS FOR TRANSITION from a example in-tree to a product:
 *
 * While this could be used indefinitely, it does not exemplify orderly management of
 * application-injected resources. It is recommended for actual products to instead:
 *   - Use the basic ServerInitParams in the application
 *   - Have the application own an instance of the resources being injected in its own
 *     state (e.g. an implementation of PersistentStorageDelegate and GroupDataProvider
 *     interfaces).
 *   - Initialize the injected resources prior to calling Server::Init()
 *   - De-initialize the injected resources after calling Server::Shutdown()
 *
 * WARNING: DO NOT replicate the pattern shown here of having a subclass of ServerInitParams
 *          own the resources outside of examples. This was done to reduce the amount of change
 *          to existing examples while still supporting non-example versions of the
 *          resources to be injected.
 */
struct CommonCaseDeviceServerInitParams : public ServerInitParams
{
    CommonCaseDeviceServerInitParams() = default;

    // Not copyable
    CommonCaseDeviceServerInitParams(const CommonCaseDeviceServerInitParams &) = delete;
    CommonCaseDeviceServerInitParams & operator=(const CommonCaseDeviceServerInitParams &) = delete;

    /**
     * Call this before Server::Init() to initialize the internally-owned resources.
     * Server::Init() will fail if this is not done, since several params required to
     * be non-null will be null without calling this method. ** See the transition method
     * in the outer comment of this class **.
     *
     * @return CHIP_NO_ERROR on success or a CHIP_ERROR value from APIs called to initialize
     *         resources on failure.
     */
    CHIP_ERROR InitializeStaticResourcesBeforeServerInit()
    {
        // KVS-based persistent storage delegate injection
        if (persistentStorageDelegate == nullptr)
        {
            chip::DeviceLayer::PersistedStorage::KeyValueStoreManager & kvsManager =
                DeviceLayer::PersistedStorage::KeyValueStoreMgr();
            ReturnErrorOnFailure(sKvsPersistenStorageDelegate.Init(&kvsManager));
            this->persistentStorageDelegate = &sKvsPersistenStorageDelegate;
        }

        // PersistentStorageDelegate "software-based" operational key access injection
        if (this->operationalKeystore == nullptr)
        {
            // WARNING: PersistentStorageOperationalKeystore::Finish() is never called. It's fine for
            //          for examples and for now.
            ReturnErrorOnFailure(sPersistentStorageOperationalKeystore.Init(this->persistentStorageDelegate));
            this->operationalKeystore = &sPersistentStorageOperationalKeystore;
        }

        // OpCertStore can be injected but default to persistent storage default
        // for simplicity of the examples.
        if (this->opCertStore == nullptr)
        {
            // WARNING: PersistentStorageOpCertStore::Finish() is never called. It's fine for
            //          for examples and for now, since all storage is immediate for that impl.
            ReturnErrorOnFailure(sPersistentStorageOpCertStore.Init(this->persistentStorageDelegate));
            this->opCertStore = &sPersistentStorageOpCertStore;
        }

        // Injection of report scheduler WILL lead to two schedulers being allocated. As recommended above, this should only be used
        // for IN-TREE examples. If a default scheduler is desired, the basic ServerInitParams should be used by the application and
        // CommonCaseDeviceServerInitParams should not be allocated.
        if (this->reportScheduler == nullptr)
        {
            reportScheduler = &sReportScheduler;
        }

        // Session Keystore injection
        this->sessionKeystore = &sSessionKeystore;

        // Group Data provider injection
        sGroupDataProvider.SetStorageDelegate(this->persistentStorageDelegate);
        sGroupDataProvider.SetSessionKeystore(this->sessionKeystore);
        ReturnErrorOnFailure(sGroupDataProvider.Init());
        this->groupDataProvider = &sGroupDataProvider;

#if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
        ReturnErrorOnFailure(sSessionResumptionStorage.Init(this->persistentStorageDelegate));
        this->sessionResumptionStorage = &sSessionResumptionStorage;
#else
        this->sessionResumptionStorage = nullptr;
#endif

        // Inject access control delegate
        this->accessDelegate = Access::Examples::GetAccessControlDelegate();

        // Inject ACL storage. (Don't initialize it.)
        this->aclStorage = &sAclStorage;

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
        ChipLogProgress(AppServer, "Initializing subscription resumption storage...");
        ReturnErrorOnFailure(sSubscriptionResumptionStorage.Init(this->persistentStorageDelegate));
        this->subscriptionResumptionStorage = &sSubscriptionResumptionStorage;
#else
        ChipLogProgress(AppServer, "Subscription persistence not supported");
#endif

        return CHIP_NO_ERROR;
    }

private:
    static KvsPersistentStorageDelegate sKvsPersistenStorageDelegate;
    static PersistentStorageOperationalKeystore sPersistentStorageOperationalKeystore;
    static Credentials::PersistentStorageOpCertStore sPersistentStorageOpCertStore;
    static Credentials::GroupDataProviderImpl sGroupDataProvider;
    static chip::app::DefaultTimerDelegate sTimerDelegate;
    static app::reporting::ReportSchedulerImpl sReportScheduler;

#if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
    static SimpleSessionResumptionStorage sSessionResumptionStorage;
#endif
#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
    static app::SimpleSubscriptionResumptionStorage sSubscriptionResumptionStorage;
#endif
    static app::DefaultAclStorage sAclStorage;
    static Crypto::DefaultSessionKeystore sSessionKeystore;
};

/**
 * The `Server` singleton class is an aggregate for all the resources needed to run a
 * Node that is both Commissionable and mainly used as an end-node with server clusters.
 * In other words, it aggregates the state needed for the type of Node used for most
 * products that are not mainly controller/administrator role.
 *
 * This sington class expects `ServerInitParams` initialization parameters but does not
 * own the resources injected from `ServerInitParams`. Any object pointers/references
 * passed in ServerInitParams must be pre-initialized externally, and shutdown/finalized
 * after `Server::Shutdown()` is called.
 *
 * TODO: Separate lifecycle ownership for some more capabilities that should not belong to
 *       common logic, such as `GenerateShutDownEvent`.
 *
 * TODO: Replace all uses of GetInstance() to "reach in" to this state from all cluster
 *       server common logic that deal with global node state with either a common NodeState
 *       compatible with OperationalDeviceProxy/DeviceProxy, or with injection at common
 *       SDK logic init.
 */
class Server
{
public:
    CHIP_ERROR Init(const ServerInitParams & initParams);

#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
    CHIP_ERROR SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner);
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT

    /**
     * @brief Call this function to rejoin existing groups found in the GroupDataProvider
     */
    void RejoinExistingMulticastGroups();

    FabricTable & GetFabricTable() { return mFabrics; }

    CASESessionManager * GetCASESessionManager() { return &mCASESessionManager; }

    Messaging::ExchangeManager & GetExchangeManager() { return mExchangeMgr; }

    SessionManager & GetSecureSessionManager() { return mSessions; }

    SessionResumptionStorage * GetSessionResumptionStorage() { return mSessionResumptionStorage; }

    app::SubscriptionResumptionStorage * GetSubscriptionResumptionStorage() { return mSubscriptionResumptionStorage; }

    TransportMgrBase & GetTransportManager() { return mTransports; }

    Credentials::GroupDataProvider * GetGroupDataProvider() { return mGroupsProvider; }

    Crypto::SessionKeystore * GetSessionKeystore() const { return mSessionKeystore; }

#if CONFIG_NETWORK_LAYER_BLE
    Ble::BleLayer * GetBleLayerObject() { return mBleLayer; }
#endif

    CommissioningWindowManager & GetCommissioningWindowManager() { return mCommissioningWindowManager; }

    PersistentStorageDelegate & GetPersistentStorage() { return *mDeviceStorage; }

    app::FailSafeContext & GetFailSafeContext() { return mFailSafeContext; }

    TestEventTriggerDelegate * GetTestEventTriggerDelegate() { return mTestEventTriggerDelegate; }

    Crypto::OperationalKeystore * GetOperationalKeystore() { return mOperationalKeystore; }

    Credentials::OperationalCertificateStore * GetOpCertStore() { return mOpCertStore; }

    app::DefaultAttributePersistenceProvider & GetDefaultAttributePersister() { return mAttributePersister; }

    app::reporting::ReportScheduler * GetReportScheduler() { return mReportScheduler; }

    /**
     * This function causes the ShutDown event to be generated async on the
     * Matter event loop.  Should be called before stopping the event loop.
     */
    void GenerateShutDownEvent();

    void Shutdown();

    void ScheduleFactoryReset();

    System::Clock::Microseconds64 TimeSinceInit() const
    {
        return System::SystemClock().GetMonotonicMicroseconds64() - mInitTimestamp;
    }

    static Server & GetInstance() { return sServer; }

private:
    Server() {}

    static Server sServer;

    void InitFailSafe();
    void OnPlatformEvent(const DeviceLayer::ChipDeviceEvent & event);
    void CheckServerReadyEvent();

    static void OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t);

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
    /**
     * @brief Called at Server::Init time to resume persisted subscriptions if the feature flag is enabled
     */
    void ResumeSubscriptions();
#endif

    class GroupDataProviderListener final : public Credentials::GroupDataProvider::GroupListener
    {
    public:
        GroupDataProviderListener() {}

        CHIP_ERROR Init(Server * server)
        {
            VerifyOrReturnError(server != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

            mServer = server;
            return CHIP_NO_ERROR;
        };

        void OnGroupAdded(chip::FabricIndex fabric_index, const Credentials::GroupDataProvider::GroupInfo & new_group) override
        {
            const FabricInfo * fabric = mServer->GetFabricTable().FindFabricWithIndex(fabric_index);
            if (fabric == nullptr)
            {
                ChipLogError(AppServer, "Group added to nonexistent fabric?");
                return;
            }

            if (mServer->GetTransportManager().MulticastGroupJoinLeave(
                    Transport::PeerAddress::Multicast(fabric->GetFabricId(), new_group.group_id), true) != CHIP_NO_ERROR)
            {
                ChipLogError(AppServer, "Unable to listen to group");
            }
        };

        void OnGroupRemoved(chip::FabricIndex fabric_index, const Credentials::GroupDataProvider::GroupInfo & old_group) override
        {
            const FabricInfo * fabric = mServer->GetFabricTable().FindFabricWithIndex(fabric_index);
            if (fabric == nullptr)
            {
                ChipLogError(AppServer, "Group removed from nonexistent fabric?");
                return;
            }

            mServer->GetTransportManager().MulticastGroupJoinLeave(
                Transport::PeerAddress::Multicast(fabric->GetFabricId(), old_group.group_id), false);
        };

    private:
        Server * mServer;
    };

    class ServerFabricDelegate final : public chip::FabricTable::Delegate
    {
    public:
        ServerFabricDelegate() {}

        CHIP_ERROR Init(Server * server)
        {
            VerifyOrReturnError(server != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

            mServer = server;
            return CHIP_NO_ERROR;
        }

        void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override
        {
            (void) fabricTable;
            ClearCASEResumptionStateOnFabricChange(fabricIndex);
            ClearSubscriptionResumptionStateOnFabricChange(fabricIndex);

            Credentials::GroupDataProvider * groupDataProvider = mServer->GetGroupDataProvider();
            if (groupDataProvider != nullptr)
            {
                CHIP_ERROR err = groupDataProvider->RemoveFabric(fabricIndex);
                if (err != CHIP_NO_ERROR)
                {
                    ChipLogError(AppServer,
                                 "Warning, failed to delete GroupDataProvider state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
                                 static_cast<unsigned>(fabricIndex), err.Format());
                }
            }

            // Remove access control entries in reverse order (it could be any order, but reverse order
            // will cause less churn in persistent storage).
            CHIP_ERROR aclErr = Access::GetAccessControl().DeleteAllEntriesForFabric(fabricIndex);
            if (aclErr != CHIP_NO_ERROR)
            {
                ChipLogError(AppServer, "Warning, failed to delete access control state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
                             static_cast<unsigned>(fabricIndex), aclErr.Format());
            }

            //  Remove ACL extension entry for the given fabricIndex.
            auto & storage = mServer->GetPersistentStorage();
            aclErr = storage.SyncDeleteKeyValue(DefaultStorageKeyAllocator::AccessControlExtensionEntry(fabricIndex).KeyName());

            if (aclErr != CHIP_NO_ERROR && aclErr != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
            {
                ChipLogError(AppServer, "Warning, failed to delete ACL extension entry for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
                             static_cast<unsigned>(fabricIndex), aclErr.Format());
            }

            mServer->GetCommissioningWindowManager().OnFabricRemoved(fabricIndex);
        }

        void OnFabricUpdated(const FabricTable & fabricTable, chip::FabricIndex fabricIndex) override
        {
            (void) fabricTable;
            ClearCASEResumptionStateOnFabricChange(fabricIndex);
        }

    private:
        void ClearCASEResumptionStateOnFabricChange(chip::FabricIndex fabricIndex)
        {
            auto * sessionResumptionStorage = mServer->GetSessionResumptionStorage();
            VerifyOrReturn(sessionResumptionStorage != nullptr);
            CHIP_ERROR err = sessionResumptionStorage->DeleteAll(fabricIndex);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(AppServer,
                             "Warning, failed to delete session resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
                             static_cast<unsigned>(fabricIndex), err.Format());
            }
        }

        void ClearSubscriptionResumptionStateOnFabricChange(chip::FabricIndex fabricIndex)
        {
            auto * subscriptionResumptionStorage = mServer->GetSubscriptionResumptionStorage();
            VerifyOrReturn(subscriptionResumptionStorage != nullptr);
            CHIP_ERROR err = subscriptionResumptionStorage->DeleteAll(fabricIndex);
            if (err != CHIP_NO_ERROR)
            {
                ChipLogError(AppServer,
                             "Warning, failed to delete subscription resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
                             static_cast<unsigned>(fabricIndex), err.Format());
            }
        }

        Server * mServer = nullptr;
    };

    /**
     * Since root certificates for Matter nodes cannot be updated in a reasonable
     * way, it doesn't make sense to enforce expiration time on root certificates.
     * This policy allows through root certificates, even if they're expired, and
     * otherwise delegates to the provided policy, or to the default policy if no
     * policy is provided.
     */
    class IgnoreRootExpirationValidityPolicy : public Credentials::CertificateValidityPolicy
    {
    public:
        IgnoreRootExpirationValidityPolicy() {}

        void Init(Credentials::CertificateValidityPolicy * providedPolicy) { mProvidedPolicy = providedPolicy; }

        CHIP_ERROR ApplyCertificateValidityPolicy(const Credentials::ChipCertificateData * cert, uint8_t depth,
                                                  Credentials::CertificateValidityResult result) override
        {
            switch (result)
            {
            case Credentials::CertificateValidityResult::kExpired:
            case Credentials::CertificateValidityResult::kExpiredAtLastKnownGoodTime:
            case Credentials::CertificateValidityResult::kTimeUnknown: {
                uint8_t certType;
                ReturnErrorOnFailure(cert->mSubjectDN.GetCertType(certType));
                if (certType == Credentials::kCertType_Root)
                {
                    return CHIP_NO_ERROR;
                }

                break;
            }
            default:
                break;
            }

            if (mProvidedPolicy)
            {
                return mProvidedPolicy->ApplyCertificateValidityPolicy(cert, depth, result);
            }

            return Credentials::CertificateValidityPolicy::ApplyDefaultPolicy(cert, depth, result);
        }

    private:
        Credentials::CertificateValidityPolicy * mProvidedPolicy = nullptr;
    };

#if CONFIG_NETWORK_LAYER_BLE
    Ble::BleLayer * mBleLayer = nullptr;
#endif

    // By default, use a certificate validation policy compatible with non-wall-clock-time-synced
    // embedded systems.
    static Credentials::IgnoreCertificateValidityPeriodPolicy sDefaultCertValidityPolicy;

    ServerTransportMgr mTransports;
    SessionManager mSessions;
    CASEServer mCASEServer;

    CASESessionManager mCASESessionManager;
    CASEClientPool<CHIP_CONFIG_DEVICE_MAX_ACTIVE_CASE_CLIENTS> mCASEClientPool;
    OperationalSessionSetupPool<CHIP_CONFIG_DEVICE_MAX_ACTIVE_DEVICES> mSessionSetupPool;

    Protocols::SecureChannel::UnsolicitedStatusHandler mUnsolicitedStatusHandler;
    Messaging::ExchangeManager mExchangeMgr;
    FabricTable mFabrics;
    secure_channel::MessageCounterManager mMessageCounterManager;
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
    chip::Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient gUDCClient;
#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
    CommissioningWindowManager mCommissioningWindowManager;

    IgnoreRootExpirationValidityPolicy mCertificateValidityPolicy;

    PersistentStorageDelegate * mDeviceStorage;
    SessionResumptionStorage * mSessionResumptionStorage;
    app::SubscriptionResumptionStorage * mSubscriptionResumptionStorage;
    Credentials::GroupDataProvider * mGroupsProvider;
    Crypto::SessionKeystore * mSessionKeystore;
    app::DefaultAttributePersistenceProvider mAttributePersister;
    GroupDataProviderListener mListener;
    ServerFabricDelegate mFabricDelegate;
    app::reporting::ReportScheduler * mReportScheduler;

    Access::AccessControl mAccessControl;
    app::AclStorage * mAclStorage;

    TestEventTriggerDelegate * mTestEventTriggerDelegate;
    Crypto::OperationalKeystore * mOperationalKeystore;
    Credentials::OperationalCertificateStore * mOpCertStore;
    app::FailSafeContext mFailSafeContext;

    bool mIsDnssdReady = false;
    uint16_t mOperationalServicePort;
    uint16_t mUserDirectedCommissioningPort;
    Inet::InterfaceId mInterfaceId;

    System::Clock::Microseconds64 mInitTimestamp;
#if CHIP_CONFIG_ENABLE_ICD_SERVER
    app::ICDEventManager mICDEventManager;
    app::ICDManager mICDManager;
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
};

} // namespace chip
