/*
 *
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *    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 subscription client for Weave
 *      Data Management (WDM) profile.
 *
 */

#ifndef _WEAVE_DATA_MANAGEMENT_SUBSCRIPTION_CLIENT_CURRENT_H
#define _WEAVE_DATA_MANAGEMENT_SUBSCRIPTION_CLIENT_CURRENT_H

#include <Weave/Core/WeaveCore.h>

#include <Weave/Profiles/data-management/TraitCatalog.h>
#include <Weave/Profiles/data-management/TraitPathStore.h>
#include <Weave/Profiles/data-management/UpdateClient.h>
#include <Weave/Profiles/data-management/UpdateEncoder.h>
#include <Weave/Profiles/data-management/EventLogging.h>
#include <Weave/Profiles/status-report/StatusReportProfile.h>

namespace nl {
namespace Weave {
namespace Profiles {
namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {

typedef uint32_t PropertyPathHandle;
typedef uint16_t PropertySchemaHandle;
typedef uint16_t PropertyDictionaryKey;
typedef uint16_t TraitDataHandle;

/**
 * @class IWeaveWDMMutex
 *
 * @brief Interface of a mutex object. Mutexes of this type are implemented by the application
 * and used in WDM to protect data structures that can be accessed from multiple threads.
 * Implementations of this interface must behave like a recursive lock.
 */

class IWeaveWDMMutex
{
public:
    virtual void Lock(void)   = 0;
    virtual void Unlock(void) = 0;
};

class SubscriptionClient
{
public:
    enum
    {
        kNoTimeOut = 0,

        // Note the WDM spec says 0x7FFFFFFF, but Weave implementation can only hold timeout of much shorter
        // 32-bit in milliseconds, which is about 1200 hours
        kMaxTimeoutSec = 3600000,
    };

    enum EventID
    {
        /**
         * Marks the end of this subscription. The parameters sent to the
         * ::nl::Weave::Profiles::DataManagement_Current::SubscriptionClient::EventCallback
         * will indicate whether a resubscribe will be automatically attempted.
         *
         * During the event handler call, the state of the client will be `Terminated`.
         * If no retry will be attempted, the state of the client will transition to
         * `Initialized` when the event handler returns.  Otherwise, the state will
         * transition to `ResubscribeHoldoff` and an attempt will be made to re-establish
         * the subscription after the hold-off time.
         *
         * The application may call AbortSubscription() or Free() in this state.
         *
         * The parameters sent will also include an error code indicating the
         * reason for ending the subscription.
         *
         * The subscription could have been terminated for a number of reasons
         * (WRM ACK missing, ExchangeContext allocation failure, response
         * timeout,...)  Some possible error codes generated by the client:
         *
         * |Error code | Meaning |
         * |-----------|---------|
         * | #WEAVE_ERROR_INVALID_MESSAGE_TYPE | An unrecognized message is received. |
         * | #WEAVE_ERROR_TIMEOUT | An ack is not received or a liveness check fails.|
         * | #WEAVE_ERROR_INCORRECT_STATE | Messages are received in an unexpected state. |
         * | #WEAVE_ERROR_STATUS_REPORT_RECEIVED | A status report is received. |
         * | #WEAVE_ERROR_INVALID_ARGUMENT | Subscribe request fields are invalid. |
         */
        kEvent_OnSubscriptionTerminated = 1,

        /**
         * Generated after the binding has been prepared and ExchangeContext has
         * been set up but prior to any messages being sent.  This is the last
         * chance for an application to adjust ExchangeContext settings, `mEC`
         * is valid and can be tuned for timeout settings.  The application must
         * not touch other fields in the client and must not close the
         * ExchangeContext.
         */
        kEvent_OnExchangeStart = 2,

        /**
         * Sent when the engine is ready to send the SubscribeRequest.  The
         * application is expected to fill in the paths that it wants to
         * subscribe to.
         */
        kEvent_OnSubscribeRequestPrepareNeeded = 3,

        /**
         * Generated upon a successful establishment of the subscription.  The
         * application may call EndSubscription(), AbortSubscription(), or
         * Free() at this point.
         */
        kEvent_OnSubscriptionEstablished = 4,

        /**
         * Generated on a receit of a NotificationRequest. The application may
         * call EndSubscription(), AbortSubscription(), or Free() at this point.
         */
        kEvent_OnNotificationRequest = 5,

        /**
         * Generated when the SubscriptionEngine finishes proceesing a
         * NotificationRequest message. The application may call
         * EndSubscription(), AbortSubscription(), or Free() at this point.
         */
        kEvent_OnNotificationProcessed = 6,

        /**
         * Generated when the SubscriptionEngine encountes an event stream
         * within the NotificationRequest message. The application may call
         * EndSubscription(), AbortSubscription(), or Free() at this point.
         */
        kEvent_OnEventStreamReceived = 7,

        /**
         * An event indicating subscription activity.  It is generated whenever
         * the client receives an indication on subscription activity; this
         * includes successful subscription establishment, a reception of a
         * NotificationRequest or a receipt of a status report in response to
         * the SubscribeConfirm message.
         */
        kEvent_OnSubscriptionActivity = 8,

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
        /**
         * An event denoting the completion of the update.  Event parameters
         * will indicate whether the update of a specific trait path has
         * succeeded or failed.
         */
        kEvent_OnUpdateComplete = 9,

        /**
         * An event denoting that all paths in the update set have been
         * processed by the peer, and no more paths need to be updated.
         */
        kEvent_OnNoMorePendingUpdates = 10,
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE
    };

    struct LastObservedEvent
    {
        uint64_t mSourceId;
        uint8_t mImportance;
        uint64_t mEventId;
    };

    // union of structures for each event some of them might be empty
    union InEventParam
    {
        void Clear(void) { memset(this, 0, sizeof(*this)); }

        struct
        {
            WEAVE_ERROR mReason;

            bool mIsStatusCodeValid;
            uint32_t mStatusProfileId;
            uint16_t mStatusCode;
            ReferencedTLVData * mAdditionalInfoPtr;
            bool mWillRetry;

            SubscriptionClient * mClient;
        } mSubscriptionTerminated;

        struct
        {
            // Do not close the EC
            nl::Weave::ExchangeContext * mEC;
            SubscriptionClient * mClient;
        } mExchangeStart;

        struct
        {
            SubscriptionClient * mClient;
        } mSubscribeRequestPrepareNeeded;

        struct
        {
            uint64_t mSubscriptionId;
            SubscriptionClient * mClient;
        } mSubscriptionEstablished;

        struct
        {
            // Do not close the EC
            nl::Weave::ExchangeContext * mEC;

            // Do not modify the message content
            PacketBuffer * mMessage;
            SubscriptionClient * mClient;
        } mNotificationRequest;

        struct
        {
            SubscriptionClient * mClient;
        } mNotificationProcessed;

        struct
        {
            nl::Weave::TLV::TLVReader * mReader;
            SubscriptionClient * mClient;
        } mEventStreamReceived;

        struct
        {
            SubscriptionClient * mClient;
        } mSubscriptionActivity;

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
        struct
        {
            WEAVE_ERROR mReason;
            uint32_t mStatusProfileId;
            uint16_t mStatusCode;
            TraitDataHandle mTraitDataHandle;
            PropertyPathHandle mPropertyPathHandle;
            SubscriptionClient * mClient;
            bool mWillRetry;
        } mUpdateComplete;
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE
    };

    union OutEventParam
    {
        void Clear(void) { memset(this, 0, sizeof(*this)); }

        struct
        {
            TraitPath * mPathList;                   ///< Pointer to a list of trait paths
            VersionedTraitPath * mVersionedPathList; ///< Pointer to a list of versioned trait paths. If both this and mPathList are
                                                     ///< non-NULL, the versioned path list is selected
            size_t mPathListSize;                    ///< Number of trait paths in mPathList
            LastObservedEvent * mLastObservedEventList; ///< A list of the last known events received by the subscriber
            size_t mLastObservedEventListSize;          ///< Number of observed events in mLastObservedEventList
            uint32_t mTimeoutSecMin;                    ///< Field specifying lower bound of liveness timeout
            uint32_t mTimeoutSecMax;                    ///< Field specifying upper bound of liveness timeout
            uint64_t mSubscriptionId;                   ///< The subscription ID to use for a mutual subscription
            bool mNeedAllEvents;                        ///< Indicates whether the subscriber is interested in events
        } mSubscribeRequestPrepareNeeded;
    };

    struct ResubscribeParam
    {
        typedef enum
        {
            kSubscription,
            kUpdate
        } RequestType;
        WEAVE_ERROR mReason;      ///< Error received on most recent failure
        uint32_t mNumRetries;     ///< Number of retries, reset on a successful attempt
        RequestType mRequestType; ///< Request being backed off
    };

    /**
     * @brief Callback to pass subscription events to application.
     *
     * @param[in] aAppState     App state pointer set during initialization of
     *                          the SubscriptionClient.
     *
     * @param[in] aEvent        Indicates which event is happening
     *
     * @param[in] aInParam      Struct with additional details about the event
     *
     * @param[out] aOutParam    Information passed back by the application
     */
    typedef void (*EventCallback)(void * const aAppState, EventID aEvent, const InEventParam & aInParam, OutEventParam & aOutParam);

    static void DefaultEventHandler(EventID aEvent, const InEventParam & aInParam, OutEventParam & aOutParam);

    /**
     * @brief Callback to fetch the interval of time to wait before the next
     * resubscribe. Applications are allowed to abort/free in this function
     * if they've decided to give up on resubscribing.
     *
     * @param[in] aAppState         App state pointer set during initialization of
     *                              the SubscriptionClient.
     *
     * @param[in] aInParam          Struct with additional details about the retry
     *
     * @param[out] aOutIntervalMsec Time in milliseconds to wait before next retry
     */
    typedef void (*ResubscribePolicyCallback)(void * const aAppState, ResubscribeParam & aInParam, uint32_t & aOutIntervalMsec);

    static void DefaultResubscribePolicyCallback(void * const aAppState, ResubscribeParam & aInParam, uint32_t & aOutIntervalMsec);

    void InitiateSubscription(void);
    void InitiateCounterSubscription(const uint32_t aLivenessTimeoutSec);

    Binding * GetBinding(void) const;

    uint64_t GetPeerNodeId(void) const;

    /**
     * @brief
     *   End the subscription.
     *
     * When #WDM_ENABLE_SUBSCRIPTION_CANCEL compile-time option is enabled,
     * gracefully end the subscription by sending a CancelRequest to the peer.
     * The resources associated with the subscription are freed on response
     * from the peer or on timeout.  When the option is disabled, the call is
     * equivalent to AbortSubscription().
     */
    WEAVE_ERROR EndSubscription(void);

    /**
     * @brief
     *  Abort the subscription.
     *
     * Immediately stop accepting all traffic associated with the subscription,
     * and release all underlying communication resources.  The
     * SubscriptionClient object itself remains valid and may be used again.
     */
    void AbortSubscription(void);

    /**
     * @brief
     *   Free this SubscriptionClient object.
     *
     * Calls AbortSubscription() if necessary and releases the refcount on this
     * SubscriptionClient object.  Under correct usage, this should enable the
     * object to be returned to the object pool
     */
    void Free(void);

    WEAVE_ERROR GetSubscriptionId(uint64_t * const apSubscriptionId);

    uint32_t GetLivenessTimeoutMsec(void) const { return mLivenessTimeoutMsec; };
    void SetLivenessTimeoutMsec(uint32_t val) { mLivenessTimeoutMsec = val; }

    void EnableResubscribe(ResubscribePolicyCallback aCallback);
    void DisableResubscribe(void);
    void ResetResubscribe(void);

    bool IsInProgressOrEstablished()
    {
        return (mCurrentState >= kState_InProgressOrEstablished_Begin && mCurrentState <= kState_InProgressOrEstablished_End);
    }

    bool IsRetryEnabled() { return (mResubscribePolicyCallback != NULL); }

    bool IsEstablished() { return (mCurrentState >= kState_Established_Begin && mCurrentState <= kState_Established_End); }
    bool IsEstablishedIdle() { return (mCurrentState == kState_SubscriptionEstablished_Idle); }
    bool IsFree() { return (mCurrentState == kState_Free); }
    bool IsCanceling() const { return (mCurrentState == kState_Canceling); }
    bool IsTerminated() { return (mCurrentState == kState_Terminated); }
    bool IsInResubscribeHoldoff() { return (mCurrentState == kState_Resubscribe_Holdoff); }

    void IndicateActivity(void);

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    void LockUpdateMutex(void);
    void UnlockUpdateMutex(void);

    WEAVE_ERROR FlushUpdate();
    WEAVE_ERROR FlushUpdate(bool aForce);
    WEAVE_ERROR SetUpdated(TraitUpdatableDataSink * aDataSink, PropertyPathHandle aPropertyHandle, bool aIsConditional);
    void DiscardUpdates();
    void SuspendUpdateRetries();
    void OnCatalogChanged();

    bool IsUpdatePendingOrInProgress() { return (kPendingSetEmpty != mPendingSetState || IsUpdateInProgress()); }
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE

private:
    friend class SubscriptionEngine;
    friend class TestTdm;
    friend class TestWdm;
    friend class WdmUpdateEncoderTest;
    friend class MockWdmSubscriptionInitiatorImpl;
    friend class TraitDataSink;
    friend class TraitSchemaEngine;
    friend class UpdateDirtyPathFilter;
    friend class UpdateDictionaryDirtyPathCut;
    friend class UpdateEncoder;

    enum ClientState
    {
        kState_Free                                 = 0,
        kState_Initialized                          = 1,
        kState_Subscribing                          = 2,
        kState_Subscribing_IdAssigned               = 3,
        kState_SubscriptionEstablished_Idle         = 4,
        kState_SubscriptionEstablished_Confirming   = 5,
        kState_Canceling                            = 6,
        kState_Resubscribe_Holdoff                  = 7,
        kState_Terminated                           = 8,

        kState_NotifyDataSinkOnAbort_Begin          = kState_Subscribing,
        kState_NotifyDataSinkOnAbort_End            = kState_Canceling,
        kState_TimerTick_Begin                      = kState_Subscribing,
        kState_TimerTick_End                        = kState_Resubscribe_Holdoff,

        // Note that these are the same as the allowed states in NotificationRequestHandler
        kState_InProgressOrEstablished_Begin        = kState_Subscribing,
        kState_InProgressOrEstablished_End          = kState_SubscriptionEstablished_Confirming,

        kState_Established_Begin                    = kState_SubscriptionEstablished_Idle,
        kState_Established_End                      = kState_SubscriptionEstablished_Confirming,
    };

    ClientState mCurrentState;

    /**
     * The runtime configuration; i.e. the desired state of the Client.
     */
    enum ClientConfig
    {
        kConfig_Down,             /**< The default configuration: no subscription, no binding.
                                       The client comes back to this configuration automatically if the responder
                                       sends a Cancel request. */
        kConfig_Initiator,        /**< Subscribe as an initiator */
        kConfig_CounterSubscriber /**< Start a "counter subscription" */
    };

    bool IsInitiator() { return mConfig == kConfig_Initiator; }
    bool IsCounterSubscriber() { return mConfig == kConfig_CounterSubscriber; }
    bool ShouldSubscribe() { return mConfig > kConfig_Down; }

    ClientConfig mConfig;
    bool mPrevIsPartialChange;
#if WDM_ENABLE_PROTOCOL_CHECKS
    TraitDataHandle mPrevTraitDataHandle;
#endif

    int8_t mRefCount;

    Binding * mBinding;
    nl::Weave::ExchangeContext * mEC;

    void * mAppState;
    EventCallback mEventCallback;

    Binding::EventCallback mAppBindingCallback;
    void * mAppBindingState;

    ResubscribePolicyCallback mResubscribePolicyCallback;

    TraitCatalogBase<TraitDataSink> * mDataSinkCatalog;

    ExchangeContext::Timeout mInactivityTimeoutDuringSubscribingMsec;
    uint32_t mLivenessTimeoutMsec;
    uint64_t mSubscriptionId;

    // retry params
    uint32_t mRetryCounter;

    // Do nothing
    SubscriptionClient(void);

    void InitAsFree(void);
    void Reset(void);

    // AddRef to Binding
    // store pointers to binding and delegate
    // null out EC
    WEAVE_ERROR Init(Binding * const apBinding, void * const apAppState, EventCallback const aEventCallback,
                     const TraitCatalogBase<TraitDataSink> * const apCatalog,
                     const uint32_t aInactivityTimeoutDuringSubscribingMsec, IWeaveWDMMutex * aUpdateMutex);

    void _InitiateSubscription(void);
    WEAVE_ERROR SendSubscribeRequest(void);

    void _Cleanup();

    WEAVE_ERROR ProcessDataList(nl::Weave::TLV::TLVReader & aReader);

    void _AddRef(void);
    void _Release(void);

    void TerminateSubscription(WEAVE_ERROR aReason, Profiles::StatusReporting::StatusReport * aStatusReport, bool suppressAppCallback);
    WEAVE_ERROR _PrepareBinding(void);

    WEAVE_ERROR ReplaceExchangeContext(void);

    void FlushExistingExchangeContext(const bool aAbortNow = false);

    void NotificationRequestHandler(nl::Weave::ExchangeContext * aEC, const nl::Inet::IPPacketInfo * aPktInfo,
                                    const nl::Weave::WeaveMessageInfo * aMsgInfo, PacketBuffer * aPayload);

#if WDM_ENABLE_SUBSCRIPTION_CANCEL
    void CancelRequestHandler(nl::Weave::ExchangeContext * aEC, const nl::Inet::IPPacketInfo * aPktInfo,
                              const nl::Weave::WeaveMessageInfo * aMsgInfo, PacketBuffer * aPayload);
#endif // WDM_ENABLE_SUBSCRIPTION_CANCEL

    void TimerEventHandler(void);
    WEAVE_ERROR RefreshTimer(void);

    void SetRetryTimer(WEAVE_ERROR aReason); // TODO: rename to SetResubscribeTimer()
    void CancelSubscriptionTimer(void);

    void MoveToState(const ClientState aTargetState);

    const char * GetStateStr(void) const;

    static void BindingEventCallback(void * const apAppState, const Binding::EventType aEvent,
                                     const Binding::InEventParam & aInParam, Binding::OutEventParam & aOutParam);
    static void OnTimerCallback(System::Layer * aSystemLayer, void * aAppState, System::Error aErrorCode);
    static void DataSinkOperation_NoMoreData(void * const apOpState, TraitDataSink * const apDataSink);
    static void OnSendError(ExchangeContext * aEC, WEAVE_ERROR aErrorCode, void * aMsgSpecificContext);
    static void OnResponseTimeout(nl::Weave::ExchangeContext * aEC);
    static void OnMessageReceivedFromLocallyInitiatedExchange(nl::Weave::ExchangeContext * aEC,
                                                              const nl::Inet::IPPacketInfo * aPktInfo,
                                                              const nl::Weave::WeaveMessageInfo * aMsgInfo, uint32_t aProfileId,
                                                              uint8_t aMsgType, PacketBuffer * aPayload);

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE

    IWeaveWDMMutex * mUpdateMutex;

    struct UpdateRequestContext
    {
        void Reset();

        size_t mItemInProgress;
        PropertyPathHandle mNextDictionaryElementPathHandle;
        uint32_t mUpdateRequestIndex;
        bool mIsPartialUpdate;
    };
    uint32_t mUpdateRetryCounter;
    bool mSuspendUpdateRetries;
    bool mUpdateRetryScheduled;
    bool mUpdateFlushScheduled;

    void StartUpdateRetryTimer(WEAVE_ERROR aReason);
    static void OnUpdateTimerCallback(System::Layer * aSystemLayer, void * aAppState, System::Error);
    static void OnUpdateScheduleWorkCallback(System::Layer * aSystemLayer, void * aAppState, System::Error);
    void UpdateTimerEventHandler(void);

    uint32_t GetMaxUpdateSize(void) const { return mMaxUpdateSize == 0 ? UINT16_MAX : mMaxUpdateSize; }
    void SetMaxUpdateSize(const uint32_t aMaxPayload);

    // Methods to encode and send update requests
    void FormAndSendUpdate();
    WEAVE_ERROR SendSingleUpdateRequest(void);
    static WEAVE_ERROR AddElementFunc(UpdateEncoder * aEncoder, void * apCallState, TLV::TLVWriter & aOuterWriter);
    void SetUpdateStartVersions(void);

    // Methods to handle update response and exchange failures (OnResponseTimeout, OnSendError)
    void OnUpdateResponse(WEAVE_ERROR aReason, nl::Weave::Profiles::StatusReporting::StatusReport * apStatus);
    void OnUpdateNoResponse(WEAVE_ERROR aReason);
    static bool WillRetryUpdate(WEAVE_ERROR aErr, uint32_t aStatusProfileId, uint16_t aStatusCode);

    // Methods to purge obsolete pending paths
    WEAVE_ERROR PurgePendingUpdate(void);
    void MarkFailedPendingPaths(TraitDataHandle aTraitDataHandle, TraitUpdatableDataSink & aSink,
                                const DataVersion & aLatestVersion);
    WEAVE_ERROR PurgeFailedPendingPaths(WEAVE_ERROR aErr, size_t & aCount);

    // Methods to handle potential data loss due to notifications received with updates pending or in progress
    bool FilterNotifiedPath(TraitDataHandle aTraitDataHandle, PropertyPathHandle aPropertyPathHandle,
                            const TraitSchemaEngine * const aSchemaEngine);
    void ClearPotentialDataLoss(TraitDataHandle aTraitDataHandle, TraitUpdatableDataSink & aUpdatableSink);
    bool CheckForSinksWithDataLoss();
    static void CheckForSinksWithDataLossIteratorCb(void * aDataSink, TraitDataHandle aDataHandle, void * aContext);

    // Methods to fail everything and notify the application
    void PurgeAndNotifyFailedPaths(WEAVE_ERROR aErr, TraitPathStore & aPathStore, size_t & aCount);

    // Methods to manage the pending set and in-progress list
    enum PendingSetState
    {
        kPendingSetEmpty,
        kPendingSetOpen,
        kPendingSetReady
    };
    void SetPendingSetState(PendingSetState aState);
    WEAVE_ERROR MovePendingToInProgress(void);
    WEAVE_ERROR AddItemPendingUpdateSet(const TraitPath & aItem, const TraitSchemaEngine * const aSchemaEngine);
    WEAVE_ERROR MoveInProgressToPending(void);

    // Tracking if a payload is in flight
    bool IsUpdateInFlight() { return mUpdateInFlight; }
    void SetUpdateInFlight() { mUpdateInFlight = true; }
    void ClearUpdateInFlight() { mUpdateInFlight = false; }

    // Knowing if an update is pending or in progress
    bool IsUpdateInProgress() { return (false == mInProgressUpdateList.IsEmpty()); }
    bool IsReadyToSendNewUpdate() { return (mPendingSetState == kPendingSetReady && false == IsUpdateInProgress()); }

    // Methods to notify the application
    void UpdateCompleteEventCbHelper(const TraitPath & aTraitPath, uint32_t aStatusProfileId, uint16_t aStatusCode,
                                     WEAVE_ERROR aReason, bool aWillRetry);
    void NoMorePendingEventCbHelper(void);

    // Other methods related to mUpdateClient
    static void UpdateEventCallback(void * const aAppState, UpdateClient::EventType aEvent,
                                    const UpdateClient::InEventParam & aInParam, UpdateClient::OutEventParam & aOutParam);
    void AbortUpdates(WEAVE_ERROR);

    void ConfigureUpdatableSinks(void);

    static void MovePendingToInProgressUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext);
    static void RefreshUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext);
    static void PurgePendingUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext);
    static void ConfigureUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext);
    static void CleanupUpdatableSinkTrait(void * aDataSink, TraitDataHandle aDataHandle, void * aContext);

    bool mResubscribeNeeded;
    UpdateRequestContext mUpdateRequestContext;
    uint16_t mMaxUpdateSize;
    bool mUpdateInFlight;

    // Flags used with mInProgressUpdateList
    enum
    {
        kFlag_ForceMerge = 0x4, /**< In UpdateRequest, DataElements are encoded with the "replace" format by
                                  default; this flag is used to force the encoding of
                                  dictionaries so that the items are merged.
                                  */
        kFlag_Private = 0x8,    /**< The path was created internally by the engine
                                  to encode a dictionary in its own separate
                                  DataElement; the application is notified about it
                                  only if the update fails.
                                  */

    };

    PendingSetState mPendingSetState;
    TraitPathStore mPendingUpdateSet;
    TraitPathStore::Record mPendingStore[WDM_UPDATE_MAX_ITEMS_IN_TRAIT_DIRTY_PATH_STORE];

    TraitPathStore mInProgressUpdateList;
    TraitPathStore::Record mInProgressStore[WDM_UPDATE_MAX_ITEMS_IN_TRAIT_DIRTY_PATH_STORE];

    UpdateClient mUpdateClient;
    UpdateEncoder mUpdateEncoder;
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE
};

}; // namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)
}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

#endif // _WEAVE_DATA_MANAGEMENT_SUBSCRIPTION_CLIENT_CURRENT_H
