/*
 *
 *    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 forms the crux of the TDM layer (trait data management), providing
 *      various classes that manage and process data as it applies to traits and their
 *      associated schemas.
 *
 */


#ifndef _WEAVE_DATA_MANAGEMENT_TRAIT_DATA_CURRENT_H
#define _WEAVE_DATA_MANAGEMENT_TRAIT_DATA_CURRENT_H

#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>

#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveMessageLayer.h>
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Support/CodeUtils.h>
#include <Weave/Profiles/data-management/MessageDef.h>

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

/*
 * A PropertyPathHandle is a unique 32-bit numerical hash of a WDM path relative to the root of a trait instance. It has two parts to it:
 *  - A lower 16-bit number that maps to the static portion of the schema.
 *  - Where the lower 16-bits refer to a path within a dictionary element, an upper 16-bit number is present that represents the dictionary key associated with that element.
 *    If the lower 16-bits refer to a non dictionary element, then the upper 16-bits should be 0.
 *
 * Some characteristics:
 *  - Every trait has its own property path handle space.
 *  - Every unique WDM sub-path path will have a similarly unique PropertyPathHandle.
 *  - PropertyPathHandles are auto-generated (done by hand for now) by a trait compiler from IDL and is represented as an enumerant list in the corresponding trait's header file.
 *  - With this construct, application logic never has to deal with WDM paths directly. Rather, their interactions with WDM are conducted exclusively through these handles.
 *  - There are two reserved values for path handles that have specific meaning:
 *      - 0 indicates a 'NULL' handle
 *      - 1 indicates a handle that points to the root of the trait instance.
 *
 */
typedef uint32_t PropertyPathHandle;
typedef uint16_t PropertySchemaHandle;
typedef uint16_t PropertyDictionaryKey;

/* Reserved property path handles that have special meaning */
enum {
    kNullPropertyPathHandle = 0,
    kRootPropertyPathHandle = 1
};

inline PropertyPathHandle CreatePropertyPathHandle(PropertySchemaHandle aPropertyPathSchemaId, PropertyDictionaryKey aPropertyPathDictionaryKey = 0) {
    return (((uint32_t)aPropertyPathDictionaryKey << 16) | aPropertyPathSchemaId);
}

inline PropertySchemaHandle GetPropertySchemaHandle(PropertyPathHandle aHandle) {
    return (aHandle & 0xffff);
}

inline PropertyDictionaryKey GetPropertyDictionaryKey(PropertyPathHandle aHandle) {
    return (aHandle >> 16);
}

inline bool IsRootPropertyPathHandle(PropertyPathHandle aHandle) {
    return (aHandle == kRootPropertyPathHandle);
}

inline bool IsNullPropertyPathHandle(PropertyPathHandle aHandle) {
    return (aHandle == kNullPropertyPathHandle);
}

/*
 *  @class TraitSchemaEngine
 *
 *  @brief The schema engine takes schema information associated with a particular trait and provides facilities to parse and translate that into a form usable by the WDM machinery.
 *         This includes converting from PathHandles to WDM paths (and vice versa), methods to interpret/query the schema itself and methods to help read/write out data to/from TLV given a handle.
 *
 *         The schema itself is stored in tabular form, sufficiently described to allow for generic parsing/composition of WDM paths/data for any given trait. These tables are what will be the
 *         eventual output of 'code-gen' (The term itself being somewhat misleading given the absence of any generated code :P)
 */
class TraitSchemaEngine
{
public:
    /* Provides information about a particular path handle including its parent property schema handle,
     * its context tag and its name.
     */
    struct PropertyInfo {
        PropertySchemaHandle mParentHandle;
        uint8_t mContextTag;
    };

/**
 *  @brief
 *    The main schema structure that houses the schema information.
 */
    struct Schema {
        uint32_t mProfileId;                    //< The ID of the trait profile.
        const PropertyInfo *mSchemaHandleTbl;   //< A pointer to the schema handle table, which provides parent info and context tags for each schema handle.
        uint32_t mNumSchemaHandleEntries;       //< The number of schema handles in this trait.
        uint32_t mTreeDepth;                    //< The max depth of this schema.
        uint8_t *mIsDictionaryBitfield;         //< A bitfield indicating whether each schema handle is a dictionary or not.
        uint8_t *mIsOptionalBitfield;           //< A bitfield indicating whether each schema handle is optional or not.
        uint8_t *mIsImplementedBitfield;        //< A bitfield indicating whether each optional schema handle is implemented or not.
        uint8_t *mIsNullableBitfield;           //< A bitfield indicating whether each schema handle is nullable or not.
        uint8_t *mIsEphemeralBitfield;          //< A bitfield indicating whether each schema handle is ephemeral or not.
    };

    /* While traits can have deep nested structures (which can include dictionaries), application logic is only expected to provide getters/setters for 'leaf' nodes in the schema. If one can visualize a
     * schema as a tree (a directed graph where you can have at most one parent for any given node) where branches indicate the presence of a nested structure, then this analogy fits in quite nicely.
     */
    class IDataSinkDelegate
    {
    public:
        enum DataSinkEventType {
            /* Start of replacement of an entire dictionary */
            kDataSinkEvent_DictionaryReplaceBegin,

            /* End of replacement of an entire dictionary */
            kDataSinkEvent_DictionaryReplaceEnd,

            /* Start of modification or addition of a dictionary item */
            kDataSinkEvent_DictionaryItemModifyBegin,

            /* End of modification or addition of a dictionary item */
            kDataSinkEvent_DictionaryItemModifyEnd,
        };

        /**
         * Given a path handle to a leaf node and a TLV reader, set the leaf data in the callee.
         *
         * @retval #WEAVE_NO_ERROR On success.
         * @retval other           Was unable to read out data from the reader.
         */
        virtual WEAVE_ERROR SetLeafData(PropertyPathHandle aLeafHandle, nl::Weave::TLV::TLVReader &aReader) = 0;

        /**
         * Given a path handle to a node, a TLV reader, and an indication
         * of whether a null type was received, set the data in the callee.
         * TDM will only call this function for handles that are nullable,
         * optional, ephemeral, or leafs. If aHandle is a non-leaf node
         * and is nullified, TDM will not call SetData for its children.
         *
         * @param[in] aHandle       The PropertyPathHandle in question.
         *
         * @param[inout] aReader    The TLV reader to read from.
         *
         * @param[out] aIsNull      Is aHandle nullified?
         *
         * @retval #WEAVE_NO_ERROR On success.
         * @retval other           Was unable to read out data from the reader.
         */
        virtual WEAVE_ERROR SetData(PropertyPathHandle aHandle, nl::Weave::TLV::TLVReader &aReader, bool aIsNull) = 0;

        /**
         * Signals to delegates when notable events occur while parsing dictionaries. In all cases, a property path handle is provided that provides more context on what this event applies to.
         *
         * For dictionary replace begin/ends, these handles are purely schema handles.
         * For dictionary item added/modififed events, these handles are property path handles as they contain the dictionary key as well.
         */
        virtual void OnDataSinkEvent(DataSinkEventType aType, PropertyPathHandle aHandle) = 0;
    };

    class IDataSourceDelegate
    {
    public:
        /**
         * Given a path handle to a leaf node and a TLV writer, get the data from the callee.
         *
         * @retval #WEAVE_NO_ERROR On success.
         * @retval other           Was unable to retrieve data and write it into the writer.
         */
        virtual WEAVE_ERROR GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, nl::Weave::TLV::TLVWriter &aWriter) = 0;

        /**
         * Given a path handle to a node, a TLV writer, and booleans indicating whether the
         * value is null or not present, get the data from the trait source that will build a
         * notify. If the path handle is not a leaf node, TDM will handle writing values to
         * the writer (like opening containers, nullifying the struct, etc). If a non-leaf
         * node is null or not present, TDM will not call GetData for its children.
         *
         * This function will only be called for handles that are nullable, optional,
         * ephemeral, or leafs. The expectation is that any traits with handles that
         * have those options enabled will implement appropriate logic to populate
         * aIsNull and aIsPresent.
         *
         * @param[in] aHandle       The PropertyPathHandle in question.
         *
         * @param[in] aTagToWrite   The tag to write for the aHandle.
         *
         * @param[inout] aWriter    The writer to write TLV elements to.
         *
         * @param[out] aIsNull      Is aHandle nullified? If yes, TDM will write
         *                          a null element. If aHandle is not a leaf,
         *                          TDM will skip over its children.
         *
         * @param[out] aIsPresent   Is aHandle present? If no and if aHandle
         *                          is not a leaf, TDM will skip over the
         *                          path and its children.
         *
         *
         * @retval #WEAVE_NO_ERROR On success.
         * @retval other           Was unable to retrieve data and write it into the writer.
         */
        virtual WEAVE_ERROR GetData(PropertyPathHandle aHandle,
                                    uint64_t aTagToWrite,
                                    nl::Weave::TLV::TLVWriter &aWriter,
                                    bool &aIsNull,
                                    bool &aIsPresent) = 0;

#if TDM_ENABLE_PUBLISHER_DICTIONARY_SUPPORT
        /**
         * Given a handle to a particular dictionary and some context (that is usable by the delegate to track state between invocations), return
         * the next dictionary item key.
         *
         * The context is initially set to 0 on the first call. There-after, the application is allowed to store any data
         * (up to width of a pointer) within that variable and it will be passed in un-modified on successive invocations.
         *
         * @retval #WEAVE_NO_ERROR On success.
         * @retval #WEAVE_END_OF_INPUT if there are no more keys to iterate over in the dictionary.
         *
         */
        virtual WEAVE_ERROR GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) = 0;
#endif
    };


    /**
     * Given a reader positioned at the root of a WDM path element, read out the relevant tags and provide
     * the equivalent path handle.
     *
     *
     * @retval #WEAVE_NO_ERROR                  On success.
     * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND   If a matching handle could not be found due to a
     *                                          malformed/incorrectly specified path.
     */
    WEAVE_ERROR MapPathToHandle(nl::Weave::TLV::TLVReader &aPathReader, PropertyPathHandle &aHandle) const;

    /**
     * Convert the path handle to a TLV path.
     *
     * @retval #WEAVE_NO_ERROR On success.
     * @retval other           Was unable to convert the handle to a TLV path
     */
    WEAVE_ERROR MapHandleToPath(PropertyPathHandle aHandle, nl::Weave::TLV::TLVWriter &aPathWriter) const;

    /**
     * Given a path handle and a reader positioned on the corresponding data element, process the data buffer pointed to by the reader and
     * store it into the sink by invoking the SetLeafData call whenever a leaf data item is encountered.
     *
     * @retval #WEAVE_NO_ERROR On success.
     * @retval other           Encountered errors parsing/processing the data.
     */
    WEAVE_ERROR StoreData(PropertyPathHandle aHandle, nl::Weave::TLV::TLVReader &aReader, IDataSinkDelegate *aDelegate) const;

    /**
     * Given a path handle and a writer position on the corresponding data element, retrieve leaf data from the source and write it into the buffer
     * pointed to by the writer in a schema compliant manner.
     *
     * @retval #WEAVE_NO_ERROR On success.
     * @retval other           Encountered errors writing out the data.
     */
    WEAVE_ERROR RetrieveData(PropertyPathHandle aHandle, uint64_t aTagToWrite, nl::Weave::TLV::TLVWriter &aWriter, IDataSourceDelegate *aDelegate) const;

    /**********
     *
     * Schema Query Functions
     *
     *********/

    /* Offset from the value of a path that provides the index into the table for that handle
     * It is 2 since the 0 and 1 are special handles.
     */
    static const uint32_t kHandleTableOffset = 2;

    /* Returns the property path handle of the child of a parent given the parent handle and the child's context tag.
     * If the parent happens to be in a dictionary, the key is preserved in the child.
     */
    PropertyPathHandle GetChildHandle(PropertyPathHandle aParentHandle, uint8_t aContextTag) const;

    /* Returns the property path handle of the dictionary item given its parent dictionary handle and an item
     * key.
     */
    PropertyPathHandle GetDictionaryItemHandle(PropertyPathHandle aParentHandle, uint16_t aDictionaryKey) const;

    /**
     * Returns true if the handle refers to a leaf node in the schema tree.
     *
     * @retval bool
     */
    bool IsLeaf(PropertyPathHandle aPropertyHandle) const;

    /**
     * Returns a pointer to the PropertyInfo structure describing a particular path handle.
     *
     * @retval PropertyInfo*
     */
    const PropertyInfo *GetMap(PropertyPathHandle aHandle) const;

    /**
     * Returns the tag associated with a path handle. If it's a dictionary element, this function returns the ProfileTag. Otherwise, it returns
     * context tags.
     *
     * @retval uint64_t
     */
    uint64_t GetTag(PropertyPathHandle aHandle) const;

    /**
     * Returns the parent handle of a given child path handle. Dictionary keys in the handle are preserved in the case where the parent
     * handle is also a dictionary element.
     *
     * @retval PropertyPathHandle   Handle of the parent.
     */
    PropertyPathHandle GetParent(PropertyPathHandle aHandle) const;

    /**
     * Returns the first child handle associated with a particular parent.
     *
     * @retval PropertyPathHandle   Handle of the first child.
     */
    PropertyPathHandle GetFirstChild(PropertyPathHandle aParentHandle) const;

    /**
     * Given a handle to an existing child, returns the next child handle associated with a particular parent.
     *
     * @retval PropertyPathHandle   Handle of the next child.
     */
    PropertyPathHandle GetNextChild(PropertyPathHandle aParentId, PropertyPathHandle aChildHandle) const;

    /**
     * Calculate the depth in the schema tree for a given handle.
     *
     * @retval int32_t              The depth in the tree
     */
    int32_t GetDepth(PropertyPathHandle aHandle) const;

    /**
     * Given two property handles, calculate the lowest handle that serves as a parent to both of these handles. Additionally, return the two child branches that contain each of the two handles (even
     * if they are the same).
     *
     * @retval PropertyPathHandle   Handle to the lowest parent.
     */
    PropertyPathHandle FindLowestCommonAncestor(PropertyPathHandle aHandle1, PropertyPathHandle aHandle2, PropertyPathHandle *aHandle1BranchChild, PropertyPathHandle *aHandle2BranchChild) const;

    /**
     * Returns true if the passed in profileId matches that stored in the schema.
     *
     * @retval bool
     */
    bool MatchesProfileId(uint32_t aProfileId) const;

    /**
     * Returns the profile id of the associated trait.
     *
     * @retval Trait profile id
     */
    uint32_t GetProfileId(void) const;

    /**
     * Returns true if the handle is a dictionary (and not in a dictionary - see method below).
     *
     * @retval bool
     */
    bool IsDictionary(PropertyPathHandle aHandle) const;

    /**
     * Returns true if the handle is *inside* a dictionary (a dictionary element). A user passed in handle (aDictionaryItemHandle) is updated to
     * point to the top-most dictionary element handle within the dictionary.
     *
     * @retval bool
     */
    bool IsInDictionary(PropertyPathHandle aHandle, PropertyPathHandle &aDictionaryItemHandle) const;

    bool IsNullable(PropertyPathHandle aHandle) const;
    bool IsEphemeral(PropertyPathHandle aHandle) const;
    bool IsOptional(PropertyPathHandle aHandle) const;

    /**
     * Checks if a given handle is a child of another handle. This can be an in-direct parent.
     *
     * @retval bool
     */
    bool IsParent(PropertyPathHandle aChildHandle, PropertyPathHandle aParentHandle) const;

    /**
     * Given a version range, this function checks to see if there is a compatibility intersection between that
     * and what is supported by schema that is backing this schema engine. If there is an intersection, the function will
     * return true and update the aIntersection argument passed in to reflect that results of that intersection test.
     */
    bool GetVersionIntersection(SchemaVersionRange &aVersion, SchemaVersionRange &aIntersection) const;

    /**
     * Given a provided data schema version, this will return the highest forward compatible schema version.
     */
    SchemaVersion GetHighestForwardVersion(SchemaVersion aVersion) const;

    /**
     * Given a provided data schema version, this will return the minimum compatible schema version
     */
    SchemaVersion GetLowestCompatibleVersion(SchemaVersion aVersion) const;

private:
    PropertyPathHandle _GetChildHandle(PropertyPathHandle aParentHandle, uint8_t aContextTag) const;
    bool GetBitFromPathHandleBitfield(uint8_t *aBitfield, PropertyPathHandle aPathHandle) const;

public:
    const Schema mSchema;
};

/*
 * @class  TraitDataSink
 *
 * @brief  Base abstract class that represents a particular instance of a trait on a specific external resource (client). Application
 *         developers are expected to subclass this to make a concrete sink that ingests data received from publishers.
 *
 *         It takes in a pointer to a schema that it then uses to help decipher incoming TLV data from a publisher and invoke the
 *         relevant data setter calls to pass the data up to subclasses.
 */
class TraitDataSink : private TraitSchemaEngine::IDataSinkDelegate
{
public:
    TraitDataSink(const TraitSchemaEngine *aEngine);
    const TraitSchemaEngine *GetSchemaEngine(void) const { return mSchemaEngine; }

    typedef WEAVE_ERROR (*OnChangeRejection)(uint16_t aRejectionStatusCode, uint64_t aVersion, void *aContext);

    enum ChangeFlags {
        kFirstElementInChange = (1 << 0),
        kLastElementInChange = (1 << 1)
    };

    /**
     * Given a reader that points to a data element conformant to a schema bound to this object, this method processes that data and
     * invokes the relevant SetLeafData call below for all leaf items in the buffer.
     *
     * A change rejection function can be passed in as well that will be invoked if the sink chooses to reject this data for any reason.
     *
     * @retval #WEAVE_NO_ERROR On success.
     * @retval other           Encountered errors writing out the data.
     */
    WEAVE_ERROR StoreDataElement(PropertyPathHandle aHandle, TLV::TLVReader &aReader, uint8_t aFlags, OnChangeRejection aFunc, void *aContext);

    /**
     * Retrieves the current version of the data that resides in this sink.
     */
    uint64_t GetVersion(void) const { return mVersion; }

    /**
     * Returns a boolean value that determines whether the version is valid.
     */
    bool IsVersionValid(void) const { return mHasValidVersion; }

    /**
     * Convenience function for data sinks to handle unknown leaf handles with
     * a system level tolerance for mismatched schema as defined by
     * TDM_DISABLE_STRICT_SCHEMA_COMPILANCE.
     */
    WEAVE_ERROR HandleUnknownLeafHandle(void)
    {
#if TDM_DISABLE_STRICT_SCHEMA_COMPLIANCE
        return WEAVE_NO_ERROR;
#else
        return WEAVE_ERROR_TLV_TAG_NOT_FOUND;
#endif
    }

    enum EventType {
        /* Signals the beginning of a change record which in certain scenarios can span multiple data elements over multiple notifies
         * (the latter only a possibility if the data being transmitted is unable to fit within a single packet)
         */
        kEventChangeBegin,

        /* Start of a data element */
        kEventDataElementBegin,

        /* End of a data element */
        kEventDataElementEnd,

        /* End of a change record */
        kEventChangeEnd,

        /* Start of replacement of an entire dictionary */
        kEventDictionaryReplaceBegin,

        /* End of replacement of an entire dictionary */
        kEventDictionaryReplaceEnd,

        /* Start of modification or addition of a dictionary item */
        kEventDictionaryItemModifyBegin,

        /* End of modification or addition of a dictionary item */
        kEventDictionaryItemModifyEnd,

        /* Deletion of a dictionary item */
        kEventDictionaryItemDelete,

        /* Signals the start of the processing of a notify packet
         */
        kEventNotifyRequestBegin,

        /* Signals the end of the processing of a notify packet
         */
        kEventNotifyRequestEnd,

        /* Signals the start of the processing of a view response
         * TODO: I'm not entirely convinced of the need to have this event.
         */
        kEventViewResponseBegin,

        /* Signals the end of the processing of a view response
         * TODO: I'm not entirely convinced of the need to have this event.
         */
        kEventViewResponseEnd,

        /* Signals the termination of a subscription either due to an error, or the subscription was cancelled */
        kEventSubscriptionTerminated
    };

    union InEventParam {
        struct {
            PropertyPathHandle mTargetHandle;
        } mDictionaryReplaceBegin;

        struct {
            PropertyPathHandle mTargetHandle;
        } mDictionaryReplaceEnd;

        struct {
            PropertyPathHandle mTargetHandle;
        } mDictionaryItemModifyBegin;

        struct {
            PropertyPathHandle mTargetHandle;
        } mDictionaryItemModifyEnd;

        struct {
            PropertyPathHandle mTargetHandle;
        } mDictionaryItemDelete;
    };

    /*
     * Invoked either by the base class or by an external agent (like the subscription engine) to signal the occurence of an event (of type EventType).
     * Sub-classes are expected to over-ride this if they desire to be made known of these events.
     */
    virtual WEAVE_ERROR OnEvent(uint16_t aType, void *aInEventParam) { return WEAVE_NO_ERROR; }

protected: // IDataSinkDelegate
    virtual WEAVE_ERROR SetLeafData(PropertyPathHandle aLeafHandle, nl::Weave::TLV::TLVReader &aReader) __OVERRIDE = 0;

    /*
     * Defaults to calling SetLeafData if aHandle is a leaf. DataSinks
     * can optionally implement this if they need to support nullable,
     * ephemeral, or optional properties.
     *
     * TODO: make this the defacto API, moving all the logic from
     * SetLeafData into this function.
     */
    virtual WEAVE_ERROR SetData(PropertyPathHandle aHandle,
                                nl::Weave::TLV::TLVReader &aReader,
                                bool aIsNull) __OVERRIDE;

    /* Subclass can invoke this if they desire to reject a particular data change */
    void RejectChange(uint16_t aRejectionStatusCode);

    /* Subclass can invoke this to clear out their version */
    void ClearVersion(void) { mHasValidVersion = false; }

    const TraitSchemaEngine *mSchemaEngine;
private:
    void OnDataSinkEvent(DataSinkEventType aType, PropertyPathHandle aHandle) __OVERRIDE;

    uint64_t mVersion;
    bool mHasValidVersion;
    static OnChangeRejection sChangeRejectionCb;
    static void *sChangeRejectionContext;
};

class Command;

class TraitDataSource : private TraitSchemaEngine::IDataSourceDelegate
{
public:
    TraitDataSource(const TraitSchemaEngine *aEngine);
    const TraitSchemaEngine *GetSchemaEngine(void) const { return mSchemaEngine; }

    uint64_t GetVersion(void) const { return mVersion; }

    WEAVE_ERROR ReadData(PropertyPathHandle aHandle, uint64_t aTagToWrite, TLV::TLVWriter &aWriter);

    /* Interactions with the underlying data has to always be done within a locked context. This applies to both the app logic (e.g a publisher when modifying its source data)
     * as well as to the core WDM logic (when trying to access that published data). This is required of both publishers and clients.
     */
    WEAVE_ERROR Lock(void);
    WEAVE_ERROR Unlock(void);

    void SetDirty(PropertyPathHandle aPropertyHandle);

#if TDM_ENABLE_PUBLISHER_DICTIONARY_SUPPORT
    void DeleteKey(PropertyPathHandle aPropertyHandle);
#endif

    virtual void OnCustomCommand(Command * aCommand,
            const nl::Weave::WeaveMessageInfo * aMsgInfo,
            nl::Weave::PacketBuffer * aPayload,
            const uint64_t & aCommandType,
            const bool aIsExpiryTimeValid,
            const int64_t & aExpiryTimeMicroSecond,
            const bool aIsMustBeVersionValid,
            const uint64_t & aMustBeVersion,
            nl::Weave::TLV::TLVReader & aArgumentReader);

    /*
     * Invoked either by the base class or by an external agent (like the subscription engine) to signal the occurrence of an event (of type EventType).
     * Sub-classes are expected to over-ride this if they desire to be made known of these events.
     */
    virtual WEAVE_ERROR OnEvent(uint16_t aType, void *aInEventParam) { return WEAVE_NO_ERROR; }

#if (WEAVE_CONFIG_WDM_PUBLISHER_GRAPH_SOLVER == IntermediateGraphSolver)
    /* Set of functions to be called by the intermediate graph solver on the notification engine for marking/clearing this entire data source as dirty */
    void SetRootDirty(void) { mRootIsDirty = true; }
    void ClearRootDirty(void) { mRootIsDirty = false; }
    bool IsRootDirty(void) const { return mRootIsDirty; }
    bool mRootIsDirty;
#endif

protected: // IDataSourceDelegate
    /*
     * Defaults to calling GetLeafData if aHandle is a leaf. DataSources
     * can optionally implement this if they need to support nullable,
     * ephemeral, or optional properties.
     *
     * TODO: make this the defacto API, moving all the logic from
     * GetLeafData into this function.
     */
    virtual WEAVE_ERROR GetData(PropertyPathHandle aHandle,
                                uint64_t aTagToWrite,
                                nl::Weave::TLV::TLVWriter &aWriter,
                                bool &aIsNull,
                                bool &aIsPresent) __OVERRIDE;

    virtual WEAVE_ERROR GetLeafData(PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, nl::Weave::TLV::TLVWriter &aWriter)  __OVERRIDE = 0 ;

#if TDM_ENABLE_PUBLISHER_DICTIONARY_SUPPORT
    virtual WEAVE_ERROR GetNextDictionaryItemKey(PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, PropertyDictionaryKey &aKey) __OVERRIDE { return WEAVE_ERROR_INVALID_ARGUMENT; }
#endif

    void IncrementVersion(void) { mVersion++; }
    uint64_t mVersion;

    // Controls whether mVersion is incremented automatically or not.
    bool mManagedVersion;

    const TraitSchemaEngine *mSchemaEngine;
private:

    // Tracks whether SetDirty was called within a Lock/Unlock 'session'
    bool mSetDirtyCalled;
};

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

#endif // _WEAVE_DATA_MANAGEMENT_TRAIT_DATA_CURRENT_H
