/*
 *
 *    Copyright (c) 2020-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 defines objects for a CHIP Interaction Data model Engine which handle unsolicited IM message, and
 *      manage different kinds of IM client and handlers.
 *
 */

#pragma once

#include <access/AccessControl.h>
#include <app/AppBuildConfig.h>
#include <app/MessageDef/AttributeReportIBs.h>
#include <app/MessageDef/ReportDataMessage.h>
#include <lib/core/CHIPCore.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/Pool.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <protocols/Protocols.h>
#include <protocols/interaction_model/Constants.h>
#include <system/SystemPacketBuffer.h>

#include <app/AttributePathParams.h>
#include <app/CommandHandler.h>
#include <app/CommandHandlerInterface.h>
#include <app/CommandSender.h>
#include <app/ConcreteAttributePath.h>
#include <app/ConcreteCommandPath.h>
#include <app/ConcreteEventPath.h>
#include <app/DataVersionFilter.h>
#include <app/EventPathParams.h>
#include <app/ObjectList.h>
#include <app/ReadClient.h>
#include <app/ReadHandler.h>
#include <app/StatusResponse.h>
#include <app/TimedHandler.h>
#include <app/WriteClient.h>
#include <app/WriteHandler.h>
#include <app/reporting/Engine.h>
#include <app/reporting/ReportScheduler.h>
#include <app/util/attribute-metadata.h>
#include <app/util/basic-types.h>

#include <app/CASESessionManager.h>

namespace chip {
namespace app {

/**
 * @class InteractionModelEngine
 *
 * @brief This is a singleton hosting all CHIP unsolicited message processing and managing interaction model related clients and
 * handlers
 *
 */
class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler,
                               public Messaging::ExchangeDelegate,
                               public CommandHandler::Callback,
                               public ReadHandler::ManagementCallback,
                               public FabricTable::Delegate
{
public:
    /**
     * @brief Retrieve the singleton Interaction Model Engine.
     *
     *  @return  A pointer to the shared InteractionModel Engine
     *
     */
    static InteractionModelEngine * GetInstance(void);

    /**
     * Spec 8.5.1 A publisher SHALL always ensure that every fabric the node is commissioned into can create at least three
     * subscriptions to the publisher and that each subscription SHALL support at least 3 attribute/event paths.
     */
    static constexpr size_t kMinSupportedSubscriptionsPerFabric = 3;
    static constexpr size_t kMinSupportedPathsPerSubscription   = 3;
    static constexpr size_t kMinSupportedPathsPerReadRequest    = 9;
    static constexpr size_t kMinSupportedReadRequestsPerFabric  = 1;
    static constexpr size_t kReadHandlerPoolSize                = CHIP_IM_MAX_NUM_SUBSCRIPTIONS + CHIP_IM_MAX_NUM_READS;

    // TODO: Per spec, the above numbers should be 3, 3, 9, 1, however, we use a lower limit to reduce the memory usage and should
    // fix it when we have reduced the memory footprint of ReadHandlers.

    InteractionModelEngine(void);

    /**
     *  Initialize the InteractionModel Engine.
     *
     *  @param[in]    apExchangeMgr    A pointer to the ExchangeManager object.
     *  @param[in]    apFabricTable    A pointer to the FabricTable object.
     *  @param[in]    apCASESessionMgr An optional pointer to a CASESessionManager (used for re-subscriptions).
     *
     *  @retval #CHIP_ERROR_INCORRECT_STATE If the state is not equal to
     *          kState_NotInitialized.
     *  @retval #CHIP_NO_ERROR On success.
     *
     */
    CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr, FabricTable * apFabricTable,
                    reporting::ReportScheduler * reportScheduler, CASESessionManager * apCASESessionMgr = nullptr,
                    SubscriptionResumptionStorage * subscriptionResumptionStorage = nullptr);

    void Shutdown();

    Messaging::ExchangeManager * GetExchangeManager(void) const { return mpExchangeMgr; }

    /**
     * Returns a pointer to the CASESessionManager. This can return nullptr if one wasn't
     * provided in the call to Init().
     */
    CASESessionManager * GetCASESessionManager() const { return mpCASESessionMgr; }

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    /**
     * Tears down an active subscription.
     *
     * @retval #CHIP_ERROR_KEY_NOT_FOUND If the subscription is not found.
     * @retval #CHIP_NO_ERROR On success.
     */
    CHIP_ERROR ShutdownSubscription(const ScopedNodeId & aPeerNodeId, SubscriptionId aSubscriptionId);

    /**
     * Tears down active subscriptions for a given peer node ID.
     */
    void ShutdownSubscriptions(FabricIndex aFabricIndex, NodeId aPeerNodeId);

    /**
     * Tears down all active subscriptions for a given fabric.
     */
    void ShutdownSubscriptions(FabricIndex aFabricIndex);

    /**
     * Tears down all active subscriptions.
     */
    void ShutdownAllSubscriptions();
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

    uint32_t GetNumActiveReadHandlers() const;
    uint32_t GetNumActiveReadHandlers(ReadHandler::InteractionType type) const;

    /**
     * Returns the number of active readhandlers with a specific type on a specific fabric.
     */
    uint32_t GetNumActiveReadHandlers(ReadHandler::InteractionType type, FabricIndex fabricIndex) const;

    uint32_t GetNumActiveWriteHandlers() const;

    /**
     * Returns the handler at a particular index within the active handler list.
     */
    ReadHandler * ActiveHandlerAt(unsigned int aIndex);

    /**
     * Returns the write handler at a particular index within the active handler list.
     */
    WriteHandler * ActiveWriteHandlerAt(unsigned int aIndex);

    /**
     * The Magic number of this InteractionModelEngine, the magic number is set during Init()
     */
    uint32_t GetMagicNumber() const { return mMagic; }

    reporting::Engine & GetReportingEngine() { return mReportingEngine; }

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

    void ReleaseAttributePathList(ObjectList<AttributePathParams> *& aAttributePathList);

    CHIP_ERROR PushFrontAttributePathList(ObjectList<AttributePathParams> *& aAttributePathList,
                                          AttributePathParams & aAttributePath);

    // If a concrete path indicates an attribute that is also referenced by a wildcard path in the request,
    // the path SHALL be removed from the list.
    void RemoveDuplicateConcreteAttributePath(ObjectList<AttributePathParams> *& aAttributePaths);

    void ReleaseEventPathList(ObjectList<EventPathParams> *& aEventPathList);

    CHIP_ERROR PushFrontEventPathParamsList(ObjectList<EventPathParams> *& aEventPathList, EventPathParams & aEventPath);

    void ReleaseDataVersionFilterList(ObjectList<DataVersionFilter> *& aDataVersionFilterList);

    CHIP_ERROR PushFrontDataVersionFilterList(ObjectList<DataVersionFilter> *& aDataVersionFilterList,
                                              DataVersionFilter & aDataVersionFilter);

    CHIP_ERROR RegisterCommandHandler(CommandHandlerInterface * handler);
    CHIP_ERROR UnregisterCommandHandler(CommandHandlerInterface * handler);
    CommandHandlerInterface * FindCommandHandler(EndpointId endpointId, ClusterId clusterId);
    void UnregisterCommandHandlers(EndpointId endpointId);

    /*
     * Register an application callback to be notified of notable events when handling reads/subscribes.
     */
    void RegisterReadHandlerAppCallback(ReadHandler::ApplicationCallback * mpApplicationCallback)
    {
        mpReadHandlerApplicationCallback = mpApplicationCallback;
    }
    void UnregisterReadHandlerAppCallback() { mpReadHandlerApplicationCallback = nullptr; }

    /**
     * Called when a timed interaction has failed (i.e. the exchange it was
     * happening on has closed while the exchange delegate was the timed
     * handler).
     */
    void OnTimedInteractionFailed(TimedHandler * apTimedHandler);

    /**
     * Called when a timed invoke is received.  This function takes over all
     * handling of the exchange, status reporting, and so forth.
     */
    void OnTimedInvoke(TimedHandler * apTimedHandler, Messaging::ExchangeContext * apExchangeContext,
                       const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload);

    /**
     * Called when a timed write is received.  This function takes over all
     * handling of the exchange, status reporting, and so forth.
     */
    void OnTimedWrite(TimedHandler * apTimedHandler, Messaging::ExchangeContext * apExchangeContext,
                      const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload);

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    /**
     * Add a read client to the internally tracked list of weak references. This list is used to
     * correctly dispatch unsolicited reports to the right matching handler by subscription ID.
     */
    void AddReadClient(ReadClient * apReadClient);

    /**
     * Remove a read client from the internally tracked list of weak references.
     */
    void RemoveReadClient(ReadClient * apReadClient);

    /**
     * Test to see if a read client is in the actively tracked list.
     */
    bool InActiveReadClientList(ReadClient * apReadClient);

    /**
     * Return the number of active read clients being tracked by the engine.
     */
    size_t GetNumActiveReadClients();
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

    /**
     * Returns the number of dirty subscriptions. Including the subscriptions that are generating reports.
     */
    size_t GetNumDirtySubscriptions() const;

    /**
     * Returns whether the write operation to the given path is conflict with another write operations. (i.e. another write
     * transaction is in the middle of processing the chunked value of the given path.)
     */
    bool HasConflictWriteRequests(const WriteHandler * apWriteHandler, const ConcreteAttributePath & aPath);

    /**
     * Select the oldest (and the one that exceeds the per subscription resource minimum if there are any) read handler on the
     * fabric with the given fabric index. Evict it when the fabric uses more resources than the per fabric quota or aForceEvict is
     * true.
     *
     * @retval Whether we have evicted a subscription.
     */
    bool TrimFabricForSubscriptions(FabricIndex aFabricIndex, bool aForceEvict);

    /**
     * Select a read handler and abort the read transaction if the fabric is using more resources (number of paths or number of read
     * handlers) then we guaranteed.
     *
     * - The youngest oversized read handlers will be chosen first.
     * - If there are no oversized read handlers, the youngest read handlers will be chosen.
     *
     * @retval Whether we have evicted a read transaction.
     */
    bool TrimFabricForRead(FabricIndex aFabricIndex);

    /**
     * Returns the minimal value of guaranteed subscriptions per fabic. UINT16_MAX will be returned if current app is configured to
     * use heap for the object pools used by interaction model engine.
     *
     * @retval the minimal value of guaranteed subscriptions per fabic.
     */
    uint16_t GetMinGuaranteedSubscriptionsPerFabric() const;

    // virtual method from FabricTable::Delegate
    void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override;

    SubscriptionResumptionStorage * GetSubscriptionResumptionStorage() { return mpSubscriptionResumptionStorage; };

    CHIP_ERROR ResumeSubscriptions();

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    //
    // Get direct access to the underlying read handler pool
    //
    auto & GetReadHandlerPool() { return mReadHandlers; }

    //
    // Override the maximal capacity of the fabric table only for interaction model engine
    //
    // If -1 is passed in, no override is instituted and default behavior resumes.
    //
    void SetConfigMaxFabrics(int32_t sz) { mMaxNumFabricsOverride = sz; }

    //
    // Override the maximal capacity of the underlying read handler pool to mimic
    // out of memory scenarios in unit-tests. You need to SetConfigMaxFabrics to make GetGuaranteedReadRequestsPerFabric
    // working correctly.
    //
    // If -1 is passed in, no override is instituted and default behavior resumes.
    //
    void SetHandlerCapacityForReads(int32_t sz) { mReadHandlerCapacityForReadsOverride = sz; }
    void SetHandlerCapacityForSubscriptions(int32_t sz) { mReadHandlerCapacityForSubscriptionsOverride = sz; }

    //
    // Override the maximal capacity of the underlying attribute path pool and event path pool to mimic
    // out of paths exhausted scenarios in unit-tests.
    //
    // If -1 is passed in, no override is instituted and default behavior resumes.
    //
    void SetPathPoolCapacityForReads(int32_t sz) { mPathPoolCapacityForReadsOverride = sz; }
    void SetPathPoolCapacityForSubscriptions(int32_t sz) { mPathPoolCapacityForSubscriptionsOverride = sz; }

    //
    // We won't limit the handler used per fabric on platforms that are using heap for memory pools, so we introduces a flag to
    // enforce such check based on the configured size. This flag is used for unit tests only, there is another compare time flag
    // CHIP_CONFIG_IM_FORCE_FABRIC_QUOTA_CHECK for stress tests.
    //
    void SetForceHandlerQuota(bool forceHandlerQuota) { mForceHandlerQuota = forceHandlerQuota; }

    //
    // When testing subscriptions using the high-level APIs in src/controller/ReadInteraction.h,
    // they don't provide for the ability to shut down those subscriptions after they've been established.
    //
    // So for the purposes of unit tests, add a helper here to shut down and clean-up all active handlers.
    //
    void ShutdownActiveReads()
    {
#if CHIP_CONFIG_ENABLE_READ_CLIENT
        for (auto * readClient = mpActiveReadClientList; readClient != nullptr;)
        {
            readClient->mpImEngine = nullptr;
            auto * tmpClient       = readClient->GetNextClient();
            readClient->SetNextClient(nullptr);
            readClient->Close(CHIP_NO_ERROR);
            readClient = tmpClient;
        }

        //
        // After that, we just null out our tracker.
        //
        mpActiveReadClientList = nullptr;
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

        mReadHandlers.ReleaseAll();
    }
#endif

private:
    friend class reporting::Engine;
    friend class TestCommandInteraction;
    friend class TestInteractionModelEngine;
    using Status = Protocols::InteractionModel::Status;

    void OnDone(CommandHandler & apCommandObj) override;
    void OnDone(ReadHandler & apReadObj) override;

    ReadHandler::ApplicationCallback * GetAppCallback() override { return mpReadHandlerApplicationCallback; }

    CHIP_ERROR OnUnsolicitedMessageReceived(const PayloadHeader & payloadHeader, ExchangeDelegate *& newDelegate) override;

    /**
     * Called when Interaction Model receives a Command Request message.
     */
    Status OnInvokeCommandRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
                                  System::PacketBufferHandle && aPayload, bool aIsTimedInvoke);
    CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
                                 System::PacketBufferHandle && aPayload) override;
    void OnResponseTimeout(Messaging::ExchangeContext * ec) override;

    /**
     * This parses the attribute path list to ensure it is well formed. If so, for each path in the list, it will expand to a list
     * of concrete paths and walk each path to check if it has privileges to read that attribute.
     *
     * If there is AT LEAST one "existent path" (as the spec calls it) that has sufficient privilege, aHasValidAttributePath
     * will be set to true. Otherwise, it will be set to false.
     *
     * aRequestedAttributePathCount will be updated to reflect the number of attribute paths in the request.
     *
     *
     */
    static CHIP_ERROR ParseAttributePaths(const Access::SubjectDescriptor & aSubjectDescriptor,
                                          AttributePathIBs::Parser & aAttributePathListParser, bool & aHasValidAttributePath,
                                          size_t & aRequestedAttributePathCount);

    /**
     * This parses the event path list to ensure it is well formed. If so, for each path in the list, it will expand to a list
     * of concrete paths and walk each path to check if it has privileges to read that event.
     *
     * If there is AT LEAST one "existent path" (as the spec calls it) that has sufficient privilege, aHasValidEventPath
     * will be set to true. Otherwise, it will be set to false.
     *
     * aRequestedEventPathCount will be updated to reflect the number of event paths in the request.
     */
    static CHIP_ERROR ParseEventPaths(const Access::SubjectDescriptor & aSubjectDescriptor,
                                      EventPathIBs::Parser & aEventPathListParser, bool & aHasValidEventPath,
                                      size_t & aRequestedEventPathCount);

    /**
     * Called when Interaction Model receives a Read Request message.  Errors processing
     * the Read Request are handled entirely within this function.  If the
     * status returned is not Status::Success, the caller will send a status
     * response message with that status.
     */
    Status OnReadInitialRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
                                System::PacketBufferHandle && aPayload, ReadHandler::InteractionType aInteractionType);

    /**
     * Called when Interaction Model receives a Write Request message.  Errors processing
     * the Write Request are handled entirely within this function. If the
     * status returned is not Status::Success, the caller will send a status
     * response message with that status.
     */
    Status OnWriteRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
                          System::PacketBufferHandle && aPayload, bool aIsTimedWrite);

    /**
     * Called when Interaction Model receives a Timed Request message.  Errors processing
     * the Timed Request are handled entirely within this function. The caller pre-sets status to failure and the callee is
     * expected to set it to success if it does not want an automatic status response message to be sent.
     */
    CHIP_ERROR OnTimedRequest(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
                              System::PacketBufferHandle && aPayload, Protocols::InteractionModel::Status & aStatus);

    /**This function handles processing of un-solicited ReportData messages on the client, which can
     * only occur post subscription establishment
     */
    Status OnUnsolicitedReportData(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
                                   System::PacketBufferHandle && aPayload);

    void DispatchCommand(CommandHandler & apCommandObj, const ConcreteCommandPath & aCommandPath,
                         TLV::TLVReader & apPayload) override;
    Protocols::InteractionModel::Status CommandExists(const ConcreteCommandPath & aCommandPath) override;

    bool HasActiveRead();

    inline size_t GetPathPoolCapacityForReads() const
    {
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
        return (mPathPoolCapacityForReadsOverride == -1) ? CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS
                                                         : static_cast<size_t>(mPathPoolCapacityForReadsOverride);
#else
        return CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS;
#endif
    }

    inline size_t GetReadHandlerPoolCapacityForReads() const
    {
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
        return (mReadHandlerCapacityForReadsOverride == -1) ? CHIP_IM_MAX_NUM_READS
                                                            : static_cast<size_t>(mReadHandlerCapacityForReadsOverride);
#else
        return CHIP_IM_MAX_NUM_READS;
#endif
    }

    inline size_t GetPathPoolCapacityForSubscriptions() const
    {
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
        return (mPathPoolCapacityForSubscriptionsOverride == -1) ? CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS
                                                                 : static_cast<size_t>(mPathPoolCapacityForSubscriptionsOverride);
#else
        return CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS;
#endif
    }

    inline size_t GetReadHandlerPoolCapacityForSubscriptions() const
    {
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
        return (mReadHandlerCapacityForSubscriptionsOverride == -1)
            ? CHIP_IM_MAX_NUM_SUBSCRIPTIONS
            : static_cast<size_t>(mReadHandlerCapacityForSubscriptionsOverride);
#else
        return CHIP_IM_MAX_NUM_SUBSCRIPTIONS;
#endif
    }

    inline uint8_t GetConfigMaxFabrics() const
    {
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
        return (mMaxNumFabricsOverride == -1) ? CHIP_CONFIG_MAX_FABRICS : static_cast<uint8_t>(mMaxNumFabricsOverride);
#else
        return CHIP_CONFIG_MAX_FABRICS;
#endif
    }

    inline size_t GetGuaranteedReadRequestsPerFabric() const
    {
        return GetReadHandlerPoolCapacityForReads() / GetConfigMaxFabrics();
    }

    /**
     * Verify and ensure (by killing oldest read handlers that make the resources used by the current fabric exceed the fabric
     * quota)
     * - If the subscription uses resources within the per subscription limit, this function will always success by evicting
     * existing subscriptions.
     * - If the subscription uses more than per subscription limit, this function will return PATHS_EXHAUSTED if we are running out
     * of paths.
     *
     * After the checks above, we will try to ensure we have a free Readhandler for processing the subscription.
     *
     * @retval true when we have enough resources for the incoming subscription, false if not.
     */
    bool EnsureResourceForSubscription(FabricIndex aFabricIndex, size_t aRequestedAttributePathCount,
                                       size_t aRequestedEventPathCount);

    /**
     * Verify and ensure (by killing oldest read handlers that make the resources used by the current fabric exceed the fabric
     * quota) the resources for handling a new read transaction with the given resource requirments.
     * - PASE sessions will be counted in a virtual fabric (i.e. kInvalidFabricIndex will be consided as a "valid" fabric in this
     * function)
     * - If the existing resources can serve this read transaction, this function will return Status::Success.
     * - or if the resources used by read transactions in the fabric index meets the per fabric resource limit (i.e. 9 paths & 1
     * read) after accepting this read request, this function will always return Status::Success by evicting existing read
     * transactions from other fabrics which are using more than the guaranteed minimum number of read.
     * - or if the resources used by read transactions in the fabric index will exceed the per fabric resource limit (i.e. 9 paths &
     * 1 read) after accepting this read request, this function will return a failure status without evicting any existing
     * transaction.
     * - However, read transactions on PASE sessions won't evict any existing read transactions when we have already commissioned
     * CHIP_CONFIG_MAX_FABRICS fabrics on the device.
     *
     * @retval Status::Success: The read transaction can be accepted.
     * @retval Status::Busy: The remaining resource is insufficient to handle this read request, and the accessing fabric for this
     * read request will use more resources than we guaranteed, the client is expected to retry later.
     * @retval Status::PathsExhausted: The attribute / event path pool is exhausted, and the read request is requesting more
     * resources than we guaranteed.
     */
    Status EnsureResourceForRead(FabricIndex aFabricIndex, size_t aRequestedAttributePathCount, size_t aRequestedEventPathCount);

    /**
     * Helper for various ShutdownSubscriptions functions.  The subscriptions
     * that match all the provided arguments will be shut down.
     */
    void ShutdownMatchingSubscriptions(const Optional<FabricIndex> & aFabricIndex = NullOptional,
                                       const Optional<NodeId> & aPeerNodeId       = NullOptional);

    static void ResumeSubscriptionsTimerCallback(System::Layer * apSystemLayer, void * apAppState);

    template <typename T, size_t N>
    void ReleasePool(ObjectList<T> *& aObjectList, ObjectPool<ObjectList<T>, N> & aObjectPool);
    template <typename T, size_t N>
    CHIP_ERROR PushFront(ObjectList<T> *& aObjectList, T & aData, ObjectPool<ObjectList<T>, N> & aObjectPool);

    Messaging::ExchangeManager * mpExchangeMgr = nullptr;

    CommandHandlerInterface * mCommandHandlerList = nullptr;

    ObjectPool<CommandHandler, CHIP_IM_MAX_NUM_COMMAND_HANDLER> mCommandHandlerObjs;
    ObjectPool<TimedHandler, CHIP_IM_MAX_NUM_TIMED_HANDLER> mTimedHandlers;
    WriteHandler mWriteHandlers[CHIP_IM_MAX_NUM_WRITE_HANDLER];
    reporting::Engine mReportingEngine;
    reporting::ReportScheduler * mReportScheduler = nullptr;

    static constexpr size_t kReservedHandlersForReads = kMinSupportedReadRequestsPerFabric * (CHIP_CONFIG_MAX_FABRICS);
    static constexpr size_t kReservedPathsForReads    = kMinSupportedPathsPerReadRequest * kReservedHandlersForReads;

#if !CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
    static_assert(CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS >=
                      CHIP_CONFIG_MAX_FABRICS * (kMinSupportedPathsPerSubscription * kMinSupportedSubscriptionsPerFabric),
                  "CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS is too small to match the requirements of spec 8.5.1");
    static_assert(CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS >=
                      CHIP_CONFIG_MAX_FABRICS * (kMinSupportedReadRequestsPerFabric * kMinSupportedPathsPerReadRequest),
                  "CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS is too small to match the requirements of spec 8.5.1");
    static_assert(CHIP_IM_MAX_NUM_SUBSCRIPTIONS >= CHIP_CONFIG_MAX_FABRICS * kMinSupportedSubscriptionsPerFabric,
                  "CHIP_IM_MAX_NUM_SUBSCRIPTIONS is too small to match the requirements of spec 8.5.1");
    static_assert(CHIP_IM_MAX_NUM_READS >= CHIP_CONFIG_MAX_FABRICS * kMinSupportedReadRequestsPerFabric,
                  "CHIP_IM_MAX_NUM_READS is too small to match the requirements of spec 8.5.1");
#endif

    ObjectPool<ObjectList<AttributePathParams>,
               CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS + CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS>
        mAttributePathPool;
    ObjectPool<ObjectList<EventPathParams>,
               CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS + CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS>
        mEventPathPool;
    ObjectPool<ObjectList<DataVersionFilter>,
               CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_READS + CHIP_IM_SERVER_MAX_NUM_PATH_GROUPS_FOR_SUBSCRIPTIONS>
        mDataVersionFilterPool;

    ObjectPool<ReadHandler, CHIP_IM_MAX_NUM_READS + CHIP_IM_MAX_NUM_SUBSCRIPTIONS> mReadHandlers;

#if CHIP_CONFIG_ENABLE_READ_CLIENT
    ReadClient * mpActiveReadClientList = nullptr;
#endif

    ReadHandler::ApplicationCallback * mpReadHandlerApplicationCallback = nullptr;

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
    int mReadHandlerCapacityForSubscriptionsOverride = -1;
    int mPathPoolCapacityForSubscriptionsOverride    = -1;

    int mReadHandlerCapacityForReadsOverride = -1;
    int mPathPoolCapacityForReadsOverride    = -1;

    int mMaxNumFabricsOverride = -1;

    // We won't limit the handler used per fabric on platforms that are using heap for memory pools, so we introduces a flag to
    // enforce such check based on the configured size. This flag is used for unit tests only, there is another compare time flag
    // CHIP_CONFIG_IM_FORCE_FABRIC_QUOTA_CHECK for stress tests.
    bool mForceHandlerQuota = false;
#endif

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION
    bool HasSubscriptionsToResume();
    uint32_t ComputeTimeSecondsTillNextSubscriptionResumption();
    uint32_t mNumSubscriptionResumptionRetries = 0;
    bool mSubscriptionResumptionScheduled      = false;
#endif

    FabricTable * mpFabricTable;

    CASESessionManager * mpCASESessionMgr = nullptr;

    SubscriptionResumptionStorage * mpSubscriptionResumptionStorage = nullptr;

    // A magic number for tracking values between stack Shutdown()-s and Init()-s.
    // An ObjectHandle is valid iff. its magic equals to this one.
    uint32_t mMagic = 0;
};

void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
                                  CommandHandler * apCommandObj);

/**
 *  Check whether the given cluster exists on the given endpoint and supports
 *  the given command.  If it does, Success will be returned.  If it does not,
 *  one of UnsupportedEndpoint, UnsupportedCluster, or UnsupportedCommand
 *  will be returned, depending on how the command fails to exist.
 */
Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCommandPath & aCommandPath);

/**
 *  Fetch attribute value and version info and write to the AttributeReport provided.
 *  The ReadSingleClusterData will do everything required for encoding an attribute, i.e. it will try to put one or more
 * AttributeReportIB to the AttributeReportIBs::Builder.
 *  When the endpoint / cluster / attribute data specified by aPath does not exist, corresponding interaction
 * model error code will be put into aAttributeReports, and CHIP_NO_ERROR will be returned. If the data exists on the server, the
 * data (with tag kData) and the data version (with tag kDataVersion) will be put into aAttributeReports. TLVWriter error will be
 * returned if any error occurred while encoding these values. This function is implemented by CHIP as a part of cluster data
 * storage & management.
 *
 *  @param[in]    aSubjectDescriptor    The subject descriptor for the read.
 *  @param[in]    aPath                 The concrete path of the data being read.
 *  @param[in]    aAttributeReports      The TLV Builder for Cluter attribute builder.
 *
 *  @retval  CHIP_NO_ERROR on success
 */
CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered,
                                 const ConcreteReadAttributePath & aPath, AttributeReportIBs::Builder & aAttributeReports,
                                 AttributeValueEncoder::AttributeEncodeState * apEncoderState);

/**
 *  Check whether concrete attribute path is an "existent attribute path" in spec terms.
 *  @param[in]    aPath                 The concrete path of the data being read.
 *  @retval  boolean   true if the concrete attribute path indicates an attribute that exists on the node.
 */
bool ConcreteAttributePathExists(const ConcreteAttributePath & aPath);

/**
 *  Get the registered attribute access override. nullptr when attribute access override is not found.
 *
 * TODO(#16806): This function and registerAttributeAccessOverride can be member functions of InteractionModelEngine.
 */
AttributeAccessInterface * GetAttributeAccessOverride(EndpointId aEndpointId, ClusterId aClusterId);

/**
 * TODO: Document.
 */
CHIP_ERROR WriteSingleClusterData(const Access::SubjectDescriptor & aSubjectDescriptor,
                                  const ConcreteDataAttributePath & aAttributePath, TLV::TLVReader & aReader,
                                  WriteHandler * apWriteHandler);

/**
 * Check if the given cluster has the given DataVersion.
 */
bool IsClusterDataVersionEqual(const ConcreteClusterPath & aConcreteClusterPath, DataVersion aRequiredVersion);

/**
 * Returns true if device type is on endpoint, false otherwise.
 */
bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint);

/**
 * Returns the metadata of the attribute for the given path.
 *
 * @retval The metadata of the attribute, will return null if the given attribute does not exists.
 */
const EmberAfAttributeMetadata * GetAttributeMetadata(const ConcreteAttributePath & aPath);

/**
 * Returns the event support status for the given event, as an interaction model status.
 */
Protocols::InteractionModel::Status CheckEventSupportStatus(const ConcreteEventPath & aPath);

} // namespace app
} // namespace chip
