/*
 *
 *    Copyright (c) 2020 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 read handler for a CHIP Interaction Data model
 *
 */

#pragma once

#include <access/AccessControl.h>
#include <app/AttributeAccessInterface.h>
#include <app/AttributePathExpandIterator.h>
#include <app/AttributePathParams.h>
#include <app/CASESessionManager.h>
#include <app/DataVersionFilter.h>
#include <app/EventManagement.h>
#include <app/EventPathParams.h>
#include <app/MessageDef/AttributePathIBs.h>
#include <app/MessageDef/DataVersionFilterIBs.h>
#include <app/MessageDef/EventFilterIBs.h>
#include <app/MessageDef/EventPathIBs.h>
#include <app/OperationalSessionSetup.h>
#include <app/SubscriptionResumptionSessionEstablisher.h>
#include <app/SubscriptionResumptionStorage.h>
#include <lib/core/CHIPCallback.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/TLVDebug.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/DLLUtil.h>
#include <lib/support/LinkedList.h>
#include <lib/support/logging/CHIPLogging.h>
#include <messaging/ExchangeHolder.h>
#include <messaging/ExchangeMgr.h>
#include <messaging/Flags.h>
#include <protocols/Protocols.h>
#include <system/SystemPacketBuffer.h>

// https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/61a9d19e6af12fdfb0872bcff26d19de6c680a1a/src/Ch02_Architecture.adoc#1122-subscribe-interaction-limits
inline constexpr uint16_t kSubscriptionMaxIntervalPublisherLimit = 3600; // seconds (60 minutes)

namespace chip {
namespace app {

//
// Forward declare the Engine (which is in a different namespace) to be able to use
// it as a friend class below.
//
namespace reporting {
class Engine;
class TestReportingEngine;
class ReportScheduler;
class TestReportScheduler;
} // namespace reporting

class InteractionModelEngine;

/**
 *  @class ReadHandler
 *
 *  @brief The read handler is responsible for processing a read request, asking the attribute/event store
 *         for the relevant data, and sending a reply.
 *
 */
class ReadHandler : public Messaging::ExchangeDelegate
{
public:
    using SubjectDescriptor = Access::SubjectDescriptor;

    enum class InteractionType : uint8_t
    {
        Read,
        Subscribe,
    };

    /*
     * A callback used to interact with the application.
     */
    class ApplicationCallback
    {
    public:
        virtual ~ApplicationCallback() = default;

        /*
         * Called right after a SubscribeRequest has been parsed and processed. This notifies an interested application
         * of a subscription that is about to be established. It also provides an avenue for altering the parameters of the
         * subscription (specifically, the min/max negotiated intervals) or even outright rejecting the subscription for
         * application-specific reasons.
         *
         * TODO: Need a new IM status code to convey application-rejected subscribes. Currently, a Failure IM status code is sent
         * back to the subscriber, which isn't sufficient.
         *
         * To reject the subscription, a CHIP_ERROR code that is not equivalent to CHIP_NO_ERROR should be returned.
         *
         * More information about the set of paths associated with this subscription can be retrieved by calling the appropriate
         * Get* methods below.
         *
         * aReadHandler:            Reference to the ReadHandler associated with the subscription.
         * aSecureSession:          A reference to the underlying secure session associated with the subscription.
         *
         */
        virtual CHIP_ERROR OnSubscriptionRequested(ReadHandler & aReadHandler, Transport::SecureSession & aSecureSession)
        {
            return CHIP_NO_ERROR;
        }

        /*
         * Called after a subscription has been fully established.
         */
        virtual void OnSubscriptionEstablished(ReadHandler & aReadHandler){};

        /*
         * Called right before a subscription is about to get terminated. This is only called on subscriptions that were terminated
         * after they had been fully established (and therefore had called OnSubscriptionEstablished).
         * OnSubscriptionEstablishment().
         */
        virtual void OnSubscriptionTerminated(ReadHandler & aReadHandler){};
    };

    /*
     * A callback used to manage the lifetime of the ReadHandler object.
     */
    class ManagementCallback
    {
    public:
        virtual ~ManagementCallback() = default;

        /*
         * Method that signals to a registered callback that this object
         * has completed doing useful work and is now safe for release/destruction.
         */
        virtual void OnDone(ReadHandler & apReadHandlerObj) = 0;

        /*
         * Retrieve the ApplicationCallback (if a valid one exists) from our management entity. This avoids
         * storing multiple references to the application provided callback and having to subsequently manage lifetime
         * issues w.r.t the ReadHandler itself.
         */
        virtual ApplicationCallback * GetAppCallback() = 0;

        /*
         * Retrieve the InteractionalModelEngine that holds this ReadHandler.
         */
        virtual InteractionModelEngine * GetInteractionModelEngine() = 0;
    };

    // TODO (#27675) : Merge existing callback and observer into one class and have an observer pool in the Readhandler to notify
    // every
    /*
     * Observer class for ReadHandler, meant to allow multiple objects to observe the ReadHandler. Currently only one observer is
     * supported but all above callbacks should be merged into observer type and an observer pool should be added to allow multiple
     * objects to observe ReadHandler
     */
    class Observer
    {
    public:
        virtual ~Observer() = default;

        /// @brief Callback invoked to notify a subscription was successfully established for the ReadHandler
        /// @param[in] apReadHandler  ReadHandler that completed its subscription
        virtual void OnSubscriptionEstablished(ReadHandler * apReadHandler) = 0;

        /// @brief Callback invoked when a ReadHandler went from a non reportable state to a reportable state. Indicates to the
        /// observer that a report should be emitted when the min interval allows it.
        ///
        /// This will only be invoked for subscribe-type ReadHandler objects, and only after
        /// OnSubscriptionEstablished has been called.
        ///
        /// @param[in] apReadHandler  ReadHandler that became dirty and in HandlerState::CanStartReporting state
        virtual void OnBecameReportable(ReadHandler * apReadHandler) = 0;

        /// @brief Callback invoked when the read handler needs to make sure to send a message to the subscriber within the next
        /// maxInterval time period.
        /// @param[in] apReadHandler ReadHandler that has generated a report
        virtual void OnSubscriptionReportSent(ReadHandler * apReadHandler) = 0;

        /// @brief Callback invoked when a ReadHandler is getting removed so it can be unregistered
        /// @param[in] apReadHandler  ReadHandler getting destroyed
        virtual void OnReadHandlerDestroyed(ReadHandler * apReadHandler) = 0;
    };

    /*
     * Destructor - as part of destruction, it will abort the exchange context
     * if a valid one still exists.
     *
     * See Abort() for details on when that might occur.
     */
    ~ReadHandler() override;

    /**
     *
     *  Constructor.
     *
     *  The callback passed in has to outlive this handler object.
     *
     */
    ReadHandler(ManagementCallback & apCallback, Messaging::ExchangeContext * apExchangeContext, InteractionType aInteractionType,
                Observer * observer);

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
    /**
     *
     *  Constructor in preparation for resuming a persisted subscription
     *
     *  The callback passed in has to outlive this handler object.
     *
     */
    ReadHandler(ManagementCallback & apCallback, Observer * observer);
#endif

    const SingleLinkedListNode<AttributePathParams> * GetAttributePathList() const { return mpAttributePathList; }
    const SingleLinkedListNode<EventPathParams> * GetEventPathList() const { return mpEventPathList; }
    const SingleLinkedListNode<DataVersionFilter> * GetDataVersionFilterList() const { return mpDataVersionFilterList; }

    void GetReportingIntervals(uint16_t & aMinInterval, uint16_t & aMaxInterval) const
    {
        aMinInterval = mMinIntervalFloorSeconds;
        aMaxInterval = mMaxInterval;
    }

    CHIP_ERROR SetMinReportingIntervalForTests(uint16_t aMinInterval)
    {
        VerifyOrReturnError(IsIdle(), CHIP_ERROR_INCORRECT_STATE);
        VerifyOrReturnError(aMinInterval <= mMaxInterval, CHIP_ERROR_INVALID_ARGUMENT);
        // Ensures the new min interval is higher than the subscriber established one.
        mMinIntervalFloorSeconds = std::max(mMinIntervalFloorSeconds, aMinInterval);
        return CHIP_NO_ERROR;
    }

    /*
     * Set the maximum reporting interval for the subscription. This SHALL only be called
     * from the OnSubscriptionRequested callback above. The restriction is as below
     * MinIntervalFloor ≤ MaxInterval ≤ MAX(SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT, MaxIntervalCeiling)
     * Where SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT is set to 60m in the spec.
     */
    CHIP_ERROR SetMaxReportingInterval(uint16_t aMaxInterval)
    {
        VerifyOrReturnError(IsIdle(), CHIP_ERROR_INCORRECT_STATE);
        VerifyOrReturnError(mMinIntervalFloorSeconds <= aMaxInterval, CHIP_ERROR_INVALID_ARGUMENT);
        VerifyOrReturnError(aMaxInterval <= std::max(GetPublisherSelectedIntervalLimit(), mMaxInterval),
                            CHIP_ERROR_INVALID_ARGUMENT);
        mMaxInterval = aMaxInterval;
        return CHIP_NO_ERROR;
    }

#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
    /**
     *
     *  @brief Initialize a ReadHandler for a resumed subsciption
     *
     *  Used after the SubscriptionResumptionSessionEstablisher establishs the CASE session
     */
    void OnSubscriptionResumed(const SessionHandle & sessionHandle, SubscriptionResumptionSessionEstablisher & sessionEstablisher);
#endif

private:
    PriorityLevel GetCurrentPriority() const { return mCurrentPriority; }
    EventNumber & GetEventMin() { return mEventMin; }

    /**
     * Returns SUBSCRIPTION_MAX_INTERVAL_PUBLISHER_LIMIT
     * For an ICD publisher, this SHALL be set to the idle mode duration.
     * Otherwise, this SHALL be set to 60 minutes.
     */
    uint16_t GetPublisherSelectedIntervalLimit();

    enum class ReadHandlerFlags : uint8_t
    {
        // The flag indicating we are in the middle of a series of chunked report messages, this flag will be cleared during
        // sending last chunked message.
        ChunkedReport = (1 << 0),

        // Tracks whether we're in the initial phase of receiving priming
        // reports, which is always true for reads and true for subscriptions
        // prior to receiving a subscribe response.
        PrimingReports     = (1 << 1),
        ActiveSubscription = (1 << 2),
        FabricFiltered     = (1 << 3),
        // For subscriptions, we record the dirty set generation when we started to generate the last report.
        // The mCurrentReportsBeginGeneration records the generation at the start of the current report.  This only/
        // has a meaningful value while IsReporting() is true.
        //
        // mPreviousReportsBeginGeneration will be set to mCurrentReportsBeginGeneration after we send the last
        // chunk of the current report.  Anything that was dirty with a generation earlier than
        // mPreviousReportsBeginGeneration has had its value sent to the client.
        // when receiving initial request, it needs mark current handler as dirty.
        // when there is urgent event, it needs mark current handler as dirty.
        ForceDirty = (1 << 4),

        // Don't need the response for report data if true
        SuppressResponse = (1 << 5),
    };

    /**
     *  Process a read/subscribe request.  Parts of the processing may end up being asynchronous, but the ReadHandler
     *  guarantees that it will call Shutdown on itself when processing is done (including if OnReadInitialRequest
     *  returns an error).
     *
     *  @retval #Others If fails to process read request
     *  @retval #CHIP_NO_ERROR On success.
     *
     */
    void OnInitialRequest(System::PacketBufferHandle && aPayload);

    /**
     *  Send ReportData to initiator
     *
     *  @param[in]    aPayload             A payload that has read request data
     *  @param[in]    aMoreChunks          A flags indicating there will be more chunks expected to be sent for this read request
     *
     *  @retval #Others If fails to send report data
     *  @retval #CHIP_NO_ERROR On success.
     *
     *  If an error is returned, the ReadHandler guarantees that it is not in
     *  a state where it's waiting for a response.
     */
    CHIP_ERROR SendReportData(System::PacketBufferHandle && aPayload, bool aMoreChunks);

    /**
     *  Returns whether this ReadHandler represents a subscription that was created by the other side of the provided exchange.
     */
    bool IsFromSubscriber(Messaging::ExchangeContext & apExchangeContext) const;

    bool IsIdle() const { return mState == HandlerState::Idle; }

    /// @brief Returns whether the ReadHandler is in a state where it can send a report and there is data to report.
    bool ShouldStartReporting() const
    {
        // Important: Anything that changes ShouldStartReporting() from false to true
        // (which can only happen for subscriptions) must call
        // mObserver->OnBecameReportable(this).
        return CanStartReporting() && (ShouldReportUnscheduled() || IsDirty());
    }
    /// @brief CanStartReporting() is true if the ReadHandler is in a state where it could generate
    /// a (possibly empty) report if someone asked it to.
    bool CanStartReporting() const { return mState == HandlerState::CanStartReporting; }
    /// @brief ShouldReportUnscheduled() is true if the ReadHandler should be asked to generate reports
    /// without consulting the report scheduler.
    bool ShouldReportUnscheduled() const
    {
        return CanStartReporting() && (IsType(ReadHandler::InteractionType::Read) || IsPriming());
    }
    bool IsAwaitingReportResponse() const { return mState == HandlerState::AwaitingReportResponse; }

    // Resets the path iterator to the beginning of the whole report for generating a series of new reports.
    void ResetPathIterator();

    CHIP_ERROR ProcessDataVersionFilterList(DataVersionFilterIBs::Parser & aDataVersionFilterListParser);

    // if current priority is in the middle, it has valid snapshoted last event number, it check cleaness via comparing
    // with snapshotted last event number. if current priority  is in the end, no valid
    // sanpshotted last event, check with latest last event number, re-setup snapshoted checkpoint, and compare again.
    bool CheckEventClean(EventManagement & aEventManager);

    bool IsType(InteractionType type) const { return (mInteractionType == type); }
    bool IsChunkedReport() const { return mFlags.Has(ReadHandlerFlags::ChunkedReport); }
    // Is reporting indicates whether we are in the middle of a series chunks. As we will set mIsChunkedReport on the first chunk
    // and clear that flag on the last chunk, we can use mIsChunkedReport to indicate this state.
    bool IsReporting() const { return mFlags.Has(ReadHandlerFlags::ChunkedReport); }
    bool IsPriming() const { return mFlags.Has(ReadHandlerFlags::PrimingReports); }
    bool IsActiveSubscription() const { return mFlags.Has(ReadHandlerFlags::ActiveSubscription); }
    bool IsFabricFiltered() const { return mFlags.Has(ReadHandlerFlags::FabricFiltered); }
    CHIP_ERROR OnSubscribeRequest(Messaging::ExchangeContext * apExchangeContext, System::PacketBufferHandle && aPayload);
    void GetSubscriptionId(SubscriptionId & aSubscriptionId) const { aSubscriptionId = mSubscriptionId; }
    AttributePathExpandIterator * GetAttributePathExpandIterator() { return &mAttributePathExpandIterator; }

    /// @brief Notifies the read handler that a set of attribute paths has been marked dirty. This will schedule a reporting engine
    /// run if the change to the attribute path makes the ReadHandler reportable.
    /// @param aAttributeChanged Path to the attribute that was changed.
    void AttributePathIsDirty(const AttributePathParams & aAttributeChanged);
    bool IsDirty() const
    {
        return (mDirtyGeneration > mPreviousReportsBeginGeneration) || mFlags.Has(ReadHandlerFlags::ForceDirty);
    }
    void ClearForceDirtyFlag() { ClearStateFlag(ReadHandlerFlags::ForceDirty); }
    NodeId GetInitiatorNodeId() const
    {
        auto session = GetSession();
        return session == nullptr ? kUndefinedNodeId : session->GetPeerNodeId();
    }

    FabricIndex GetAccessingFabricIndex() const
    {
        auto session = GetSession();
        return session == nullptr ? kUndefinedFabricIndex : session->GetFabricIndex();
    }

    Transport::SecureSession * GetSession() const;
    SubjectDescriptor GetSubjectDescriptor() const { return GetSession()->GetSubjectDescriptor(); }

    auto GetTransactionStartGeneration() const { return mTransactionStartGeneration; }

    /// @brief Forces the read handler into a dirty state, regardless of what's going on with attributes.
    /// This can lead to scheduling of a reporting run immediately, if the min interval has been reached,
    /// or after the min interval is reached if it has not yet been reached.
    void ForceDirtyState();

    const AttributeValueEncoder::AttributeEncodeState & GetAttributeEncodeState() const { return mAttributeEncoderState; }
    void SetAttributeEncodeState(const AttributeValueEncoder::AttributeEncodeState & aState) { mAttributeEncoderState = aState; }
    uint32_t GetLastWrittenEventsBytes() const { return mLastWrittenEventsBytes; }

    // Returns the number of interested paths, including wildcard and concrete paths.
    size_t GetAttributePathCount() const { return mpAttributePathList == nullptr ? 0 : mpAttributePathList->Count(); };
    size_t GetEventPathCount() const { return mpEventPathList == nullptr ? 0 : mpEventPathList->Count(); };
    size_t GetDataVersionFilterCount() const { return mpDataVersionFilterList == nullptr ? 0 : mpDataVersionFilterList->Count(); };

    CHIP_ERROR SendStatusReport(Protocols::InteractionModel::Status aStatus);

    friend class TestReadInteraction;
    friend class chip::app::reporting::TestReportingEngine;
    friend class chip::app::reporting::TestReportScheduler;

    //
    // The engine needs to be able to Abort/Close a ReadHandler instance upon completion of work for a given read/subscribe
    // interaction. We do not want to make these methods public just to give an adjacent class in the IM access, since public
    // should really be taking application usage considerations as well. Hence, make it a friend.
    //
    friend class chip::app::reporting::Engine;
    friend class chip::app::InteractionModelEngine;

    // The report scheduler needs to be able to access StateFlag private functions ShouldStartReporting(), CanStartReporting(),
    // ForceDirtyState() and IsDirty() to know when to schedule a run so it is declared as a friend class.
    friend class chip::app::reporting::ReportScheduler;

    enum class HandlerState : uint8_t
    {
        Idle,                   ///< The handler has been initialized and is ready
        CanStartReporting,      ///< The handler has is now capable of generating reports and may generate one immediately
                                ///< or later when other criteria are satisfied (e.g hold-off for min reporting interval).
        AwaitingReportResponse, ///< The handler has sent the report to the client and is awaiting a status response.
        AwaitingDestruction,    ///< The object has completed its work and is awaiting destruction by the application.
    };

    enum class CloseOptions
    {
        kDropPersistedSubscription,
        kKeepPersistedSubscription
    };
    /**
     * Called internally to signal the completion of all work on this objecta and signal to a registered callback that it's
     * safe to release this object.
     *
     *  @param    options             This specifies whether to drop or keep the subscription
     *
     */
    void Close(CloseOptions options = CloseOptions::kDropPersistedSubscription);

    CHIP_ERROR SendSubscribeResponse();
    CHIP_ERROR ProcessSubscribeRequest(System::PacketBufferHandle && aPayload);
    CHIP_ERROR ProcessReadRequest(System::PacketBufferHandle && aPayload);
    CHIP_ERROR ProcessAttributePaths(AttributePathIBs::Parser & aAttributePathListParser);
    CHIP_ERROR ProcessEventPaths(EventPathIBs::Parser & aEventPathsParser);
    CHIP_ERROR ProcessEventFilters(EventFilterIBs::Parser & aEventFiltersParser);
    CHIP_ERROR OnStatusResponse(Messaging::ExchangeContext * apExchangeContext, System::PacketBufferHandle && aPayload,
                                bool & aSendStatusResponse);
    CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PayloadHeader & aPayloadHeader,
                                 System::PacketBufferHandle && aPayload) override;
    void OnResponseTimeout(Messaging::ExchangeContext * apExchangeContext) override;
    void MoveToState(const HandlerState aTargetState);

    const char * GetStateStr() const;

    void PersistSubscription();

    /// @brief Modifies a state flag in the read handler. If the read handler went from a
    /// non-reportable state to a reportable state, schedules a reporting engine run.
    /// @param aFlag Flag to set
    /// @param aValue Flag new value
    void SetStateFlag(ReadHandlerFlags aFlag, bool aValue = true);

    /// @brief This function call SetStateFlag with the flag value set to false, thus possibly emitting a report
    /// generation.
    /// @param aFlag Flag to clear
    void ClearStateFlag(ReadHandlerFlags aFlag);

    AttributePathExpandIterator mAttributePathExpandIterator = AttributePathExpandIterator(nullptr);

    // The current generation of the reporting engine dirty set the last time we were notified that a path we're interested in was
    // marked dirty.
    //
    // This allows us to detemine whether any paths we care about might have
    // been marked dirty after we had already sent reports for them, which would
    // mean we should report those paths again, by comparing this generation to the
    // current generation when we started sending the last set reports that we completed.
    //
    // This allows us to reset the iterator to the beginning of the current
    // cluster instead of the beginning of the whole report in AttributePathIsDirty, without
    // permanently missing dirty any paths.
    uint64_t mDirtyGeneration = 0;

    // For subscriptions, we record the timestamp when we started to generate the last report.
    // The mCurrentReportsBeginGeneration records the timestamp for the current report, which won;t be used for checking if this
    // ReadHandler is dirty.
    // mPreviousReportsBeginGeneration will be set to mCurrentReportsBeginGeneration after we sent the last chunk of the current
    // report.
    uint64_t mPreviousReportsBeginGeneration = 0;
    uint64_t mCurrentReportsBeginGeneration  = 0;
    /*
     *           (mDirtyGeneration = b > a, this is a dirty read handler)
     *        +- Start Report -> mCurrentReportsBeginGeneration = c
     *        |      +- AttributePathIsDirty (Attribute Y) -> mDirtyGeneration = d
     *        |      |     +- Last Chunk -> mPreviousReportsBeginGeneration = mCurrentReportsBeginGeneration = c
     *        |      |     |   +- (mDirtyGeneration = d) > (mPreviousReportsBeginGeneration = c), this is a dirty read handler
     *        |      |     |   |  Attribute X has a dirty generation less than c, Attribute Y has a dirty generation larger than c
     *        |      |     |   |  So Y will be included in the report but X will not be inclued in this report.
     * -a--b--c------d-----e---f---> Generation
     *  |  |
     *  |  +- AttributePathIsDirty (Attribute X) (mDirtyGeneration = b)
     *  +- mPreviousReportsBeginGeneration
     * For read handler, if mDirtyGeneration > mPreviousReportsBeginGeneration, then we regard it as a dirty read handler, and it
     * should generate report on timeout reached.
     */

    // When we don't have enough resources for a new subscription, the oldest subscription might be evicted by interaction model
    // engine, the "oldest" subscription is the subscription with the smallest generation.
    uint64_t mTransactionStartGeneration = 0;

    SubscriptionId mSubscriptionId    = 0;
    uint16_t mMinIntervalFloorSeconds = 0;
    uint16_t mMaxInterval             = 0;

    EventNumber mEventMin = 0;

    // The last schedule event number snapshoted in the beginning when preparing to fill new events to reports
    EventNumber mLastScheduledEventNumber = 0;

    // TODO: We should shutdown the transaction when the session expires.
    SessionHolder mSessionHandle;

    Messaging::ExchangeHolder mExchangeCtx;
#if CHIP_CONFIG_UNSAFE_SUBSCRIPTION_EXCHANGE_MANAGER_USE
    // TODO: this should be replaced by a pointer to the InteractionModelEngine that created the ReadHandler
    // once InteractionModelEngine is no longer a singleton (see issue 23625)
    Messaging::ExchangeManager * mExchangeMgr = nullptr;
#endif // CHIP_CONFIG_UNSAFE_SUBSCRIPTION_EXCHANGE_MANAGER_USE

    SingleLinkedListNode<AttributePathParams> * mpAttributePathList   = nullptr;
    SingleLinkedListNode<EventPathParams> * mpEventPathList           = nullptr;
    SingleLinkedListNode<DataVersionFilter> * mpDataVersionFilterList = nullptr;

    ManagementCallback & mManagementCallback;

    uint32_t mLastWrittenEventsBytes = 0;

    // The detailed encoding state for a single attribute, used by list chunking feature.
    // The size of AttributeEncoderState is 2 bytes for now.
    AttributeValueEncoder::AttributeEncodeState mAttributeEncoderState;

    // Current Handler state
    HandlerState mState            = HandlerState::Idle;
    PriorityLevel mCurrentPriority = PriorityLevel::Invalid;
    BitFlags<ReadHandlerFlags> mFlags;
    InteractionType mInteractionType = InteractionType::Read;

    // TODO (#27675): Merge all observers into one and that one will dispatch the callbacks to the right place.
    Observer * mObserver = nullptr;
};
} // namespace app
} // namespace chip
