/*
 *
 *    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 Weave message parsers and encoders for Weave
 *      Data Management (WDM) profile.
 *
 */

#ifndef _WEAVE_DATA_MANAGEMENT_MESSAGE_DEF_CURRENT_H
#define _WEAVE_DATA_MANAGEMENT_MESSAGE_DEF_CURRENT_H

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

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

/**
 *  @brief
 *    The WDM profile message types.
 *
 *  These values are called out in the data management specification.
 *
 */
enum
{
    kMsgType_ViewRequest                = 0x20,
    kMsgType_ViewResponse               = 0x21,
    kMsgType_UpdateRequest              = 0x22,
    kMsgType_InProgress                 = 0x23,
    kMsgType_SubscribeRequest           = 0x24,
    kMsgType_SubscribeResponse          = 0x25,
    kMsgType_SubscribeCancelRequest     = 0x26,
    kMsgType_SubscribeConfirmRequest    = 0x27,
    kMsgType_NotificationRequest        = 0x28,
    kMsgType_CustomCommandRequest       = 0x29,
    kMsgType_CustomCommandResponse      = 0x2A,
};

/**
 *  @brief
 *    WDM-specific status codes.
 *
 */
enum
{
    kStatus_InvalidValueInNotification      = 0x20,
    kStatus_InvalidPath                     = 0x21,
    kStatus_ExpiryTimeNotSupported          = 0x22,
    kStatus_NotTimeSyncedYet                = 0x23,
    kStatus_RequestExpiredInTime            = 0x24,
    kStatus_VersionMismatch                 = 0x25,
    kStatus_GeneralProtocolError            = 0x26,
    kStatus_SecurityError                   = 0x27,
    kStatus_InvalidSubscriptionID           = 0x28,
    kStatus_GeneralSchemaViolation          = 0x29,
    kStatus_UnpairedDeviceRejected          = 0x2A,
    kStatus_IncompatibleDataSchemaVersion   = 0x2B,
};

typedef uint16_t SchemaVersion;

struct SchemaVersionRange {
    SchemaVersionRange() { mMinVersion = 1; mMaxVersion = 1; }
    SchemaVersionRange(SchemaVersion aMaxVersion, SchemaVersion aMinVersion) { mMaxVersion = aMaxVersion; mMinVersion = aMinVersion; }
    bool operator == (const SchemaVersionRange &rhs) const { return ((rhs.mMinVersion == mMinVersion) && (rhs.mMaxVersion == mMaxVersion)); }
    bool IsValid() const { return mMinVersion <= mMaxVersion; }

    SchemaVersion mMinVersion;
    SchemaVersion mMaxVersion;
};

/**
 *  @class ParserBase
 *
 *  @brief
 *    Base class for WDM message parsers
 */
class ParserBase
{
public:
    /**
     *  @brief Initialize a TLVReader to point to the beginning of any tagged element in this request
     *
     *  @param [out] apReader   A pointer to TLVReader, which will be initialized at the specified TLV element
     *                          on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR GetReaderOnTag(const uint64_t aTagToFind, nl::Weave::TLV::TLVReader * const apReader) const;

protected:
    nl::Weave::TLV::TLVReader mReader;

    ParserBase(void);

    template<typename T>
    WEAVE_ERROR GetUnsignedInteger(const uint8_t aContextTag, T * const apLValue) const;

    template<typename T>
    WEAVE_ERROR GetSimpleValue(const uint8_t aContextTag, const nl::Weave::TLV::TLVType aTLVType, T * const apLValue) const;
};

/**
 *  @class ListParserBase
 *
 *  @brief
 *    Base class for WDM message parsers, specialized in TLV array elements like Data Lists and Version Lists
 */
class ListParserBase : public ParserBase
{
protected:

    ListParserBase(void);

public:
    // aReader has to be on the element of the array element
    WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    // aReader has to be at the beginning of some container
    WEAVE_ERROR InitIfPresent(const nl::Weave::TLV::TLVReader & aReader, const uint8_t aContextTagToFind);

    WEAVE_ERROR Next(void);
    void GetReader(nl::Weave::TLV::TLVReader * const apReader);
};

/**
 *  @class BuilderBase
 *
 *  @brief
 *    Base class for WDM message encoders
 */
class BuilderBase
{
public:
    void ResetError(void);
    WEAVE_ERROR GetError(void) const { return mError; };
    nl::Weave::TLV::TLVWriter * GetWriter(void) { return mpWriter; };

protected:
    WEAVE_ERROR mError;
    nl::Weave::TLV::TLVWriter * mpWriter;
    nl::Weave::TLV::TLVType mOuterContainerType;

    BuilderBase(void);
    void EndOfContainer(void);

    WEAVE_ERROR InitAnonymousStructure(nl::Weave::TLV::TLVWriter * const apWriter);
};

/**
 *  @class ListBuilderBase
 *
 *  @brief
 *    Base class for WDM message encoders, specialized in TLV array elements like Data Lists and Version Lists
 */
class ListBuilderBase : public BuilderBase
{
protected:

    ListBuilderBase(void);

public:

    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse);
};

/**
 *  @brief
 *    WDM Path definition
 *
 */
namespace Path
{
    enum
    {
        kCsTag_InstanceLocator          = 1,

        kCsTag_ResourceID               = 1,
        kCsTag_TraitProfileID           = 2,
        kCsTag_TraitInstanceID          = 3,
    };

    class Parser;
    class Builder;
};

/**
 *  @class Parser
 *
 *  @brief
 *    Parses a WDM Path container
 */
class Path::Parser : public ParserBase
{
public:

    // aReader has to be on the element of Path container
    WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    // Roughly verify the schema is right, including
    // 1) all mandatory tags are present
    // 2) no unknown tags
    // 3) all elements have expected data type
    // 4) any tag can only appear once
    WEAVE_ERROR CheckSchemaValidity(void) const;

    // Resource ID could be of any type, so we can only position the reader so the caller has
    // full information of tag, element type, length, and value
    // WEAVE_END_OF_TLV if there is no such element
    WEAVE_ERROR GetResourceID(nl::Weave::TLV::TLVReader * const apReader) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
    WEAVE_ERROR GetResourceID(uint64_t * const apResourceID) const;

    // Instance ID could be of any type, so we can only position the reader so the caller has
    // full information of tag, element type, length, and value
    WEAVE_ERROR GetInstanceID(nl::Weave::TLV::TLVReader * const apReader) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
    WEAVE_ERROR GetInstanceID(uint64_t * const apInstanceID) const;

    // Profile ID can only be uint32_t and not any other type
    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
    WEAVE_ERROR GetProfileID(uint32_t * const apResourceID, SchemaVersionRange * const apSchemaVersionRange);

    // Get a TLVReader at the additional tags section. Next() must be called before accessing it.
    WEAVE_ERROR GetTags(nl::Weave::TLV::TLVReader * const apReader) const;
};

class Path::Builder: public BuilderBase
{
public:

    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse);

    Path::Builder & ResourceID(const uint64_t aResourceID);
    Path::Builder & InstanceID(const uint64_t aInstanceID);
    Path::Builder & ProfileID(const uint32_t aProfileID);
    Path::Builder & ProfileID(const uint32_t aProfileID, const SchemaVersionRange &aSchemaVersionRange);

    Path::Builder & TagSection(void);
    Path::Builder & AdditionalTag(const uint64_t aTagInApiForm);

    Path::Builder & EndOfPath(void);

private:
    bool mInTagSection;

    WEAVE_ERROR _Init(nl::Weave::TLV::TLVWriter * const apWriter, const uint64_t aTagInApiForm);
};

/**
 *  @brief
 *    WDM Data Element definition
 *
 */
namespace DataElement
{
    enum
    {
        kCsTag_Path                     = 1,
        kCsTag_Version                  = 2,
        kCsTag_IsPartialChange          = 3,

        /* 4-8 are reserved */
        kCsTag_DeletedDictionaryKeys    = 9,
        kCsTag_Data                     = 10,
    };

    class Parser;
    class Builder;
};

/**
 *  @brief
 *    WDM Data Element parser definition
 */
class DataElement::Parser : public ParserBase
{
public:

    // aReader has to be on the element of DataElement
    WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    // Roughly verify the schema is right, including
    // 1) all mandatory tags are present
    // 2) all elements have expected data type
    // 3) any tag can only appear once
    // At the top level of the structure, unknown tags are ignored for foward compatibility
    WEAVE_ERROR CheckSchemaValidity(void) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not a Path
    WEAVE_ERROR GetPath(Path::Parser * const apPath) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
    WEAVE_ERROR GetVersion(uint64_t * const apVersion) const;

    // on successful return, apDataPresentFlag will be TRUE if the
    // DataElement contains data, and GetData method may be called
    // without an error.  apDeletePresentFlag will be set to TRUE if this
    // DataElement contains a DictionaryDeletedKeyList.
    // WEAVE_NO_ERROR if the element is properly formatted,
    // WEAVE_ERROR_WDM_MALFORMED_DATA_ELEMENT if the element contains
    // neither the data merge element nor the deleted dictionary key
    // list
    WEAVE_ERROR CheckPresence(bool * const apDataPresentFlag, bool * const apDeletePresentFlag) const;

    // Data could be of any type, so we can only position the reader so the caller has
    // full information of tag, element type, length, and value
    WEAVE_ERROR GetData(nl::Weave::TLV::TLVReader * const apReader) const;

    // On success, the apReader is initialized to point to the first
    // element in the deleted keys list.
    // WEAVE_NO_ERROR on success.  WEAVE_ERROR_INVALID_TLV_TAG if the
    // DeletedDictionaryKeyList is not present.
    // WEAVE_ERROR_WRONG_TLV_TYPE if the element type is not a TLV
    // Array
    WEAVE_ERROR GetDeletedDictionaryKeys(nl::Weave::TLV::TLVReader * const apReader) const;

    // Default is false if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not a boolean
    WEAVE_ERROR GetPartialChangeFlag (bool * const apPartialChangeFlag) const;

    WEAVE_ERROR GetReaderOnPath (nl::Weave::TLV::TLVReader * const apReader) const;

protected:
    // A recursively callable function to parse a data element and pretty-print it.
    WEAVE_ERROR ParseData(nl::Weave::TLV::TLVReader &aReader, int aDepth) const;
};

/**
 *  @brief
 *    WDM Data Element encoder definition
 */
class DataElement::Builder: public BuilderBase
{
public:

    // DataElement is only used in a Data List, which requires every path to be anonymous
    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

    Path::Builder & CreatePathBuilder(void);

    DataElement::Builder & Version(const uint64_t aVersion);

    // Nothing would be written if aIsPartialChange == false, as that's the default value
    DataElement::Builder & PartialChange (const bool aIsPartialChange);

    DataElement::Builder & EndOfDataElement(void);

private:
    Path::Builder mPathBuilder;
};

/**
 *  @brief
 *    WDM Path List definition
 */
namespace PathList
{
    class Parser;
    class Builder;
};

class PathList::Parser : public ListParserBase
{
public:

    // Roughly verify the schema is right, including
    // 1) at least one element is there
    // 2) all elements are anonymous and of Path type
    // 3) every path is also valid in schema
    WEAVE_ERROR CheckSchemaValidity(void) const;
};

class PathList::Builder: public ListBuilderBase
{
public:

    // Re-initialize the shared PathBuilder with anonymous tag
    Path::Builder & CreatePathBuilder(void);

    // Mark the end of this array and recover the type for outer container
    PathList::Builder & EndOfPathList(void);

private:
    Path::Builder mPathBuilder;
};

namespace DataList
{
    class Parser;
    class Builder;
};

class DataList::Parser : public ListParserBase
{
public:

    // Roughly verify the schema is right, including
    // 1) at least one element is there
    // 2) all elements are anonymous and of Structure type
    // 3) every Data Element is also valid in schema
    WEAVE_ERROR CheckSchemaValidity(void) const;
};

class DataList::Builder: public ListBuilderBase
{
public:

    // Re-initialize the shared PathBuilder with anonymous tag
    DataElement::Builder & CreateDataElementBuilder(void);

    // Mark the end of this array and recover the type for outer container
    DataList::Builder & EndOfDataList(void);

private:
    DataElement::Builder mDataElementBuilder;
};

namespace Event
{
    enum
    {
        kCsTag_Source                   = 1,
        kCsTag_Importance               = 2,
        kCsTag_Id                       = 3,

        /* 4-9 are reserved */

        kCsTag_RelatedImportance        = 10,
        kCsTag_RelatedId                = 11,
        kCsTag_UTCTimestamp             = 12,
        kCsTag_SystemTimestamp          = 13,
        kCsTag_ResourceId               = 14,
        kCsTag_TraitProfileId           = 15,
        kCsTag_TraitInstanceId          = 16,
        kCsTag_Type                     = 17,

        /* 18-29 are reserved */

        kCsTag_DeltaUTCTime             = 30,
        kCsTag_DeltaSystemTime          = 31,

        /* 32-49 are reserved */

        kCsTag_Data                     = 50,
    };

    class Parser;
    class Builder;
};

class Event::Parser : protected DataElement::Parser
{
public:
    WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    // Roughly verify the schema is right
    WEAVE_ERROR CheckSchemaValidity(void) const;

    WEAVE_ERROR GetSourceId(uint64_t * const apSourceId);
    WEAVE_ERROR GetImportance(uint64_t * const apImportance);
    WEAVE_ERROR GetEventId(uint64_t * const apEventId);

    WEAVE_ERROR GetRelatedEventImportance(uint64_t * const apImportance);
    WEAVE_ERROR GetRelatedEventId(uint64_t * const apEventId);

    WEAVE_ERROR GetUTCTimestamp(uint64_t * const apUTCTimestamp);
    WEAVE_ERROR GetSystemTimestamp(uint64_t * const apSystemTimestamp);
    WEAVE_ERROR GetResourceId(uint64_t * const apResourceId);
    WEAVE_ERROR GetTraitProfileId(uint32_t * const apTraitProfileId);
    WEAVE_ERROR GetTraitInstanceId(uint64_t * const apTraitInstanceId);
    WEAVE_ERROR GetEventType(uint64_t * const apEventType);

    WEAVE_ERROR GetDeltaUTCTime(int64_t * const apDeltaUTCTime);
    WEAVE_ERROR GetDeltaSystemTime(int64_t * const apDeltaSystemTime);

    WEAVE_ERROR GetReaderOnEvent(nl::Weave::TLV::TLVReader * const apReader) const;
};

class Event::Builder: public BuilderBase
{
public:

    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

    Event::Builder SourceId(const uint64_t aSourceId);
    Event::Builder Importance(const uint64_t aImportance);
    Event::Builder EventId(const uint64_t aEventId);

    Event::Builder RelatedEventImportance(const uint64_t aImportance);
    Event::Builder RelatedEventId(const uint64_t aEventId);

    Event::Builder UTCTimestamp(const uint64_t aUTCTimestamp);
    Event::Builder SystemTimestamp(const uint64_t aSystemTimestamp);
    Event::Builder ResourceId(const uint64_t aResourceId);
    Event::Builder TraitProfileId(const uint32_t aTraitProfileId);
    Event::Builder TraitInstanceId(const uint64_t aTraitInstanceId);
    Event::Builder EventType(const uint64_t aEventType);

    Event::Builder DeltaUTCTime(const int64_t aDeltaUTCTime);
    Event::Builder DeltaSystemTime(const int64_t aDeltaSystemTime);

    // Mark the end of this array and recover the type for outer container
    Event::Builder & EndOfEvent(void);
};

namespace EventList
{
    class Parser;
    class Builder;
};

class EventList::Parser : public ListParserBase
{
public:

    // Roughly verify the schema is right, including
    // 1) at least one element is there
    // 2) all elements are anonymous and of Structure type
    // 3) every Event is also valid in schema
    WEAVE_ERROR CheckSchemaValidity(void) const;
};

class EventList::Builder: public ListBuilderBase
{
public:

    // Re-initialize the shared EventBuilder with anonymous tag
    Event::Builder & CreateEventBuilder(void);

    // Mark the end of this array and recover the type for outer container
    EventList::Builder & EndOfEventList(void);

private:
    Event::Builder mEventBuilder;
};

namespace VersionList
{
    class Parser;
    class Builder;
};

class VersionList::Parser : public ListParserBase
{
public:

    // verify the schema is right, including
    // 1) all elements are anonymous
    // 2) all elements are either null or unsigned integer
    WEAVE_ERROR CheckSchemaValidity(void) const;

    // 1) current element is anonymous
    // 2) current element is either unsigned integer or NULL
    bool IsElementValid(void);

    bool IsNull(void);
    WEAVE_ERROR GetVersion(uint64_t * const apVersion);
};

class VersionList::Builder: public ListBuilderBase
{
public:

    VersionList::Builder & AddVersion(const uint64_t aVersion);
    VersionList::Builder & AddNull(void);

    // Mark the end of this array and recover the type for outer container
    VersionList::Builder & EndOfVersionList(void);
};

namespace ViewRequest
{
    enum
    {
        kCsTag_PathList                 = 1,
    };
};

namespace ViewResponse
{
    enum
    {
        kCsTag_DataList                 = 2,
    };
};

namespace BaseMessageWithSubscribeId
{
    enum
    {
        kCsTag_SubscriptionId           = 1,
    };

    class Parser;
    class Builder;
};

class BaseMessageWithSubscribeId::Parser : public ParserBase
{
public:

    // aReader has to be on the element of anonymous container
    WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
    WEAVE_ERROR GetSubscriptionID(uint64_t * const apSubscriptionID) const;
};

class BaseMessageWithSubscribeId::Builder: public BuilderBase
{
public:
    enum
    {
        kBaseMessageSubscribeId_PayloadLen = 12, //StartContainer (1) + kCsTag_SubscriptionId TLV (10) + EndContainer (1)
    };

    // Path is mostly used in a Path List, which requires every path to be anonymous
    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

protected:
    void SetSubscriptionID(const uint64_t aSubscriptionID);
    void EndOfMessage(void);
};


namespace SubscribeRequest
{
    enum
    {
        kCsTag_SubscriptionId           = 1,
        kCsTag_SubscribeTimeOutMin      = 2,
        kCsTag_SubscribeTimeOutMax      = 3,
        kCsTag_SubscribeToAllEvents     = 4,
        kCsTag_LastObservedEventIdList  = 5,

        /* 5-19 are reserved */

        kCsTag_PathList                 = 20,
        kCsTag_VersionList              = 21,
    };

    class Parser;
    class Builder;
};

/**
 *  @brief
 *    WDM Path parser definition
 *
 */
// Note that in theory this class can be derived from SubscribeCancelRequest, but we are anticipating the tags to be changed
class SubscribeRequest::Parser : public BaseMessageWithSubscribeId::Parser
{
public:

    // aReader has to be on the element of anonymous container
    //WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    // Roughly verify the schema is right, including
    // 1) all mandatory tags are present
    // 2) no unknown tags
    // 3) all elements have expected data type
    // 4) any tag can only appear once
    WEAVE_ERROR CheckSchemaValidity(void) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
    //WEAVE_ERROR GetSubscriptionID(uint64_t * const apSubscriptionID) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetSubscribeTimeoutMin(uint32_t * const apTimeOutMin) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetSubscribeTimeoutMax(uint32_t * const apTimeOutMax) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetSubscribeToAllEvents(bool * const apAllEvents) const;

    // Get a TLVReader for the last observed events. Next() must be called before accessing them.
    WEAVE_ERROR GetLastObservedEventIdList(EventList::Parser * const apEventList) const;

    // Get a TLVReader for the Paths. Next() must be called before accessing them.
    WEAVE_ERROR GetPathList(PathList::Parser * const apPathList) const;

    // Get a TLVReader at the Versions. Next() must be called before accessing it.
    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetVersionList(VersionList::Parser * const apVersionList) const;
};

// Note that in theory this class can be derived from SubscribeCancelRequest, but we are anticipating the tags to be changed
class SubscribeRequest::Builder: public BaseMessageWithSubscribeId::Builder
{
public:

    SubscribeRequest::Builder & SubscriptionID(const uint64_t aSubscriptionID);
    SubscribeRequest::Builder & SubscribeTimeoutMin(const uint32_t aSubscribeTimeoutMin);
    SubscribeRequest::Builder & SubscribeTimeoutMax(const uint32_t aSubscribeTimeoutMax);
    SubscribeRequest::Builder & SubscribeToAllEvents(const bool aSubscribeToAllEvents);

    EventList::Builder & CreateLastObservedEventIdListBuilder(void);

    PathList::Builder & CreatePathListBuilder(void);

    VersionList::Builder & CreateVersionListBuilder(void);

    SubscribeRequest::Builder & EndOfRequest(void);

private:
    EventList::Builder mEventListBuilder;
    PathList::Builder mPathListBuilder;
    VersionList::Builder mVersionListBuilder;
};

namespace SubscribeResponse
{
    enum
    {
        kCsTag_SubscriptionId           = 1,
        kCsTag_SubscribeTimeOut         = 2,

        /* 3-9 are reserved */

        kCsTag_PossibleLossOfEvents     = 10,
        kCsTag_LastVendedEventIdList    = 11,
    };

    class Parser;
    class Builder;
};

/**
 *  @brief
 *    WDM Path parser definition
 *
 */
// Note that in theory this class can be derived from SubscribeCancelRequest, but we are anticipating the tags to be changed
class SubscribeResponse::Parser : public BaseMessageWithSubscribeId::Parser
{
public:

    // Roughly verify the schema is right, including
    // 1) all mandatory tags are present
    // 2) no unknown tags
    // 3) all elements have expected data type
    // 4) any tag can only appear once
    WEAVE_ERROR CheckSchemaValidity(void) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
    //WEAVE_ERROR GetSubscriptionID(uint64_t * const apSubscriptionID) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetSubscribeTimeout(uint32_t * const apTimeOut) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetPossibleLossOfEvents(bool * const apPossibleLossOfEvents) const;

    // Get a TLVReader for the last observed events. Next() must be called before accessing them.
    WEAVE_ERROR GetLastVendedEventIdList(EventList::Parser * const apEventList) const;
};

// Note that in theory this class can be derived from SubscribeCancelRequest, but we are anticipating the tags to be changed
class SubscribeResponse::Builder: public BaseMessageWithSubscribeId::Builder
{
public:

    // Path is mostly used in a Path List, which requires every path to be anonymous
    //WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

    SubscribeResponse::Builder & SubscriptionID(const uint64_t aSubscriptionID);
    SubscribeResponse::Builder & SubscribeTimeout(const uint32_t aSubscribeTimeout);

    SubscribeResponse::Builder & PossibleLossOfEvents(const bool aPossibleLossOfEvents);

    EventList::Builder & CreateLastVendedEventIdListBuilder(void);

    SubscribeResponse::Builder & EndOfResponse(void);

private:
    EventList::Builder mEventListBuilder;
};

namespace SubscribeCancelRequest
{
    enum
    {
        kCsTag_SubscriptionId           = 1,
    };

    class Parser;
    class Builder;
};

class SubscribeCancelRequest::Parser : public BaseMessageWithSubscribeId::Parser
{
public:

    // aReader has to be on the element of anonymous container
    //WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    // Roughly verify the schema is right, including
    // 1) all mandatory tags are present
    // 2) all elements have expected data type
    // 3) any tag can only appear once
    WEAVE_ERROR CheckSchemaValidity(void) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types
    //WEAVE_ERROR GetSubscriptionID(uint64_t * const apSubscriptionID) const;
};

class SubscribeCancelRequest::Builder: public BaseMessageWithSubscribeId::Builder
{
public:

    // Path is mostly used in a Path List, which requires every path to be anonymous
    //WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

    SubscribeCancelRequest::Builder & SubscriptionID(const uint64_t aSubscriptionID);
    SubscribeCancelRequest::Builder & EndOfRequest(void);
};

namespace SubscribeConfirmRequest
{
    enum
    {
        kCsTag_SubscriptionId           = 1,
    };

    class Parser;
    class Builder;
};

class SubscribeConfirmRequest::Parser : public SubscribeCancelRequest::Parser
{
    // exactly the same as cancel, even the member function CheckSchemaValidity
};

class SubscribeConfirmRequest::Builder : public BaseMessageWithSubscribeId::Builder
{
public:
    SubscribeConfirmRequest::Builder & SubscriptionID(const uint64_t aSubscriptionID);
    SubscribeConfirmRequest::Builder & EndOfRequest(void);
};

namespace RejectionRecord
{
    enum
    {
        kCsTag_Path                     = 1,
        kCsTag_Version                  = 2,
        kCsTag_Reason                   = 3,
    };

    class Parser;
    class Builder;
};

class RejectionRecord::Parser : public ParserBase
{
public:

    // aReader has to be on the element of Event
    WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    // Roughly verify the schema is right
    WEAVE_ERROR CheckSchemaValidity(void) const;

};

class RejectionRecord::Builder: public BuilderBase
{
public:

    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

    // Mark the end of this array and recover the type for outer container
    DataList::Builder & EndOfRecord(void);
};

namespace RejectionRecordList
{
    enum
    {
        kCsTag_RejectionRecordList      = 1,
    };

    class Parser;
    class Builder;
};

class RejectionRecordList::Parser : public ListParserBase
{
public:

    // Roughly verify the schema is right, including
    // 1) at least one element is there
    // 2) all elements are anonymous and of Structure type
    // 3) every Event is also valid in schema
    WEAVE_ERROR CheckSchemaValidity(void) const;

private:
    RejectionRecord::Parser mRejectionRecordParser;
};

class RejectionRecordList::Builder: public ListBuilderBase
{
public:

    // Re-initialize the shared RejectionRecord::Builder with anonymous tag
    RejectionRecord::Builder & CreateRejectionRecord(void);

    // Mark the end of this array and recover the type for outer container
    EventList::Builder & EndOfRejectionRecordList(void);

private:
    RejectionRecord::Builder mRejectionRecordBuilder;
};

namespace NotificationRequest
{
    enum
    {
        kCsTag_SubscriptionId           = 1,

        /* 2-9 are reserved */

        kCsTag_DataList                 = 10,

        /* 11-19 are reserved */

        kCsTag_PossibleLossOfEvent      = 20,
        kCsTag_UTCTimestamp             = 21,
        kCsTag_SystemTimestamp          = 22,
        kCsTag_EventList                = 23,
    };

    class Parser;
    class Builder;
};

class NotificationRequest::Parser : public BaseMessageWithSubscribeId::Parser
{
public:

    // Roughly verify the schema is right, including
    // 1) all mandatory tags are present
    // 2) no unknown tags
    // 3) all elements have expected data type
    // 4) any tag can only appear once
    WEAVE_ERROR CheckSchemaValidity(void) const;

    // Get a TLVReader for the Paths. Next() must be called before accessing them.
    WEAVE_ERROR GetDataList(DataList::Parser * const apDataList) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetPossibleLossOfEvent(bool * const apPossibleLossOfEvent) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetUTCTimestamp(uint64_t * const apUTCTimestamp) const;

    // WEAVE_END_OF_TLV if there is no such element
    // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not one of the right types
    WEAVE_ERROR GetSystemTimestamp(uint64_t * const apSystemTimestamp) const;

    // Get a TLVReader for the events. Next() must be called before accessing them.
    WEAVE_ERROR GetEventList(EventList::Parser * const apEventList) const;
};

/**
 *  @brief
 *    WDM Custom Command Request definition
 *
 */
namespace CustomCommandRequest
{
    /// @brief Context-Specific tags used in this message
    enum
    {
        kCsTag_Path                     = 1,
        kCsTag_CommandType              = 2,
        kCsTag_ExpiryTime               = 3,
        kCsTag_MustBeVersion            = 4,

        /* 5-19 are reserved */
        kCsTag_Argument                 = 20,
    };

    class Parser;
    class Builder;
};

/**
 *  @brief
 *    WDM Custom Command Request parser definition
 */
class CustomCommandRequest::Parser : protected DataElement::Parser
{
public:

    /**
     *  @brief Initialize the parser object with TLVReader
     *
     *  @param [in] aReader A pointer to a TLVReader, which should point to the beginning of this request
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    /**
     *  @brief Roughly verify the message is correctly formed
     *
     *  @note The main use of this function is to print out what we're
     *    receiving during protocol development and debugging.
     *    The encoding rule has changed in WDM Next so this
     *    check is only "roughly" conformant now.
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR CheckSchemaValidity(void) const;

    /**
     *  @brief Initialize a Path::Parser with the path component in this request
     *
     *  @param [out] apPath A pointer to a Path::Parser, which will be
     *                      initialized with embedded path component on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     *  @retval #WEAVE_END_OF_TLV if there is no such element
     *  @retval #WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not a Path
     */
    WEAVE_ERROR GetPath(Path::Parser * const apPath) const;

    /**
     *  @brief Get the command type id for this request
     *
     *  @param [out] apCommandType  A pointer to some variable to receive
     *                              the command type id on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     *  @retval #WEAVE_END_OF_TLV if there is no such element
     *  @retval #WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not an unsigned integer
     */
    WEAVE_ERROR GetCommandType(uint64_t * const apCommandType) const;

    /**
     *  @brief Get the expiry time for this request
     *
     *  @param [out] apExpiryTimeMicroSecond    A pointer to some variable to receive
     *                                          the expiry time on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     *  @retval #WEAVE_END_OF_TLV if there is no such element
     *  @retval #WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not a signed integer
     */
    WEAVE_ERROR GetExpiryTimeMicroSecond(int64_t * const apExpiryTimeMicroSecond) const;

    /**
     *  @brief Get the must-be version for this request
     *
     *  @param [out] apMustBeVersion    A pointer to some variable to receive
     *                                  the must-be version on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     *  @retval #WEAVE_END_OF_TLV if there is no such element
     *  @retval #WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not an unsigned integer
     */
    WEAVE_ERROR GetMustBeVersion(uint64_t * const apMustBeVersion) const;

    /**
     *  @brief Initialize a TLVReader to point to the beginning of the argument component in this request
     *
     *  @param [out] apReader   A pointer to TLVReader, which will be initialized at the argument TLV element
     *                          on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR GetReaderOnArgument(nl::Weave::TLV::TLVReader * const apReader) const;

    /**
     *  @brief Initialize a TLVReader to point to the beginning of the path component in this request
     *
     *  @param [out] apReader   A pointer to TLVReader, which will be initialized at the argument TLV element
     *                          on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR GetReaderOnPath(nl::Weave::TLV::TLVReader * const apReader) const;
};

/**
 *  @brief
 *    WDM Custom Command Request encoder definition
 *
 *  The argument, and the authenticator elements are not directly supported, as they do not have a fixed schema.
 */
class CustomCommandRequest::Builder: public BuilderBase
{
public:

    /**
     *  @brief Initialize a CustomCommandRequest::Builder for writing into a TLV stream
     *
     *  @param [in] apWriter    A pointer to TLVWriter
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

    /**
     *  @brief Initialize a Path::Builder for writing into the TLV stream
     *
     *  @return A reference to Path::Builder
     */
    Path::Builder & CreatePathBuilder(void);

    /**
     *  @brief Inject command type id into the TLV stream
     *
     *  @param [in] aCommandType    Command type ID for this request
     *
     *  @return A reference to *this
     */
    CustomCommandRequest::Builder & CommandType(const uint64_t aCommandType);

    /**
     *  @brief Inject expiry time into the TLV stream
     *
     *  @param [in] aExpiryTimeMicroSecond  Expiry time for this request, in microseconds since UNIX epoch
     *
     *  @return A reference to *this
     */
    CustomCommandRequest::Builder & ExpiryTimeMicroSecond(const int64_t aExpiryTimeMicroSecond);

    /**
     *  @brief Inject must-be version into the TLV stream
     *
     *  @param [in] aMustBeVersion  Trait instance in the path must be at this version for this request to be accepted
     *
     *  @return A reference to *this
     */
    CustomCommandRequest::Builder & MustBeVersion(const uint64_t aMustBeVersion);

    /**
     *  @brief Mark the end of this request
     *
     *  @return A reference to *this
     */
    CustomCommandRequest::Builder & EndOfRequest(void);

private:
    Path::Builder mPathBuilder;
};

/**
 *  @brief
 *    WDM Custom Command Response definition
 *
 */
namespace CustomCommandResponse
{
    /// @brief Context-Specific tags used in this message
    enum
    {
        kCsTag_Version                  = 1,
        kCsTag_Response                 = 2,
    };

    class Parser;
    class Builder;
};

/**
 *  @brief
 *    WDM Custom Command Response parser definition
 */
class CustomCommandResponse::Parser : protected DataElement::Parser
{
public:

    /**
     *  @brief Initialize the parser object with TLVReader
     *
     *  @param [in] aReader A pointer to a TLVReader, which should point to the beginning of this response
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR Init(const nl::Weave::TLV::TLVReader & aReader);

    /**
     *  @brief Roughly verify the message is correctly formed
     *
     *  @note The main use of this function is to print out what we're
     *    receiving during protocol development and debugging.
     *    The encoding rule has changed in WDM Next so this
     *    check is only "roughly" conformant now.
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR CheckSchemaValidity(void) const;

    /**
     *  @brief Get the trait instance version in this response
     *
     *  @param [out] apVersion    A pointer to some variable to receive
     *                            the version on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     *  @retval #WEAVE_END_OF_TLV if there is no such element
     *  @retval #WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not an unsigned integer
     */
    WEAVE_ERROR GetVersion(uint64_t * const apVersion) const;

    /**
     *  @brief Initialize a TLVReader to point to the beginning of the response component in this message
     *
     *  @param [out] apReader   A pointer to TLVReader, which will be initialized at the response TLV element
     *                          on success
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR GetReaderOnResponse(nl::Weave::TLV::TLVReader * const apReader) const;
};

/**
 *  @brief
 *    WDM Custom Command Response encoder definition
 *
 *  The response TLV element is not directly supported, as it does not have a fixed schema.
 */
class CustomCommandResponse::Builder: public BuilderBase
{
public:

    /**
     *  @brief Initialize a CustomCommandResponse::Builder for writing into a TLV stream
     *
     *  @param [in] apWriter    A pointer to TLVWriter
     *
     *  @retval #WEAVE_NO_ERROR on success
     */
    WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter);

    /**
     *  @brief Inject trait instance version into the TLV stream
     *
     *  @param [in] aVersion  Trait instance version after the command execution
     *
     *  @return A reference to *this
     */
    CustomCommandResponse::Builder & Version(const uint64_t aVersion);

    /**
     *  @brief Mark the end of this message
     *
     *  @return A reference to *this
     */
    CustomCommandResponse::Builder & EndOfResponse(void);
};

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

#endif // _WEAVE_DATA_MANAGEMENT_MESSAGE_DEF_CURRENT_H
