/*
 *
 *    Copyright (c) 2018-2019 Google LLC.
 *    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 implements the Weave Data Management mock subscription initiator.
 *
 */

#define WEAVE_CONFIG_ENABLE_FUNCT_ERROR_LOGGING 1

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif // __STDC_FORMAT_MACROS

#include <inttypes.h>
#include <new>

// Note that the choice of namespace alias must be made up front for each and every compile unit
// This is because many include paths could set the default alias to unintended target.
#include <Weave/Profiles/bulk-data-transfer/Development/BDXManagedNamespace.hpp>
#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>

#include <Weave/Core/WeaveError.h>
#include <Weave/Core/WeaveSecurityMgr.h>
#include <Weave/Support/CodeUtils.h>
#include <Weave/Profiles/WeaveProfiles.h>
#include <Weave/Profiles/data-management/DataManagement.h>
#include <Weave/Profiles/security/ApplicationKeysTraitDataSink.h>
#include "MockWdmTestVerifier.h"
#include "MockWdmSubscriptionInitiator.h"
#include "MockSinkTraits.h"
#include "MockSourceTraits.h"
#include "TestGroupKeyStore.h"

#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING

using namespace nl::Weave::TLV;
using namespace nl::Weave::Profiles;
using namespace nl::Weave::Profiles::DataManagement;
using namespace Schema::Weave::Trait::Auth::ApplicationKeysTrait;

const nl::Weave::ExchangeContext::Timeout kResponseTimeoutMsec = 15000;
const nl::Weave::ExchangeContext::Timeout kWRMPActiveRetransTimeoutMsec = 3000;
const nl::Weave::ExchangeContext::Timeout kWRMPInitialRetransTimeoutMsec = 3000;
const uint16_t kWRMPMaxRetrans = 3;
const uint16_t kWRMPAckTimeoutMsec = 200;

// Any time setting lower than this would force the subscription client to send Subscribe Confirm continuously.
uint32_t gMinimumTimeBetweenLivenessCheckSec = ((WEAVE_CONFIG_WRMP_DEFAULT_MAX_RETRANS + 1) * kWRMPActiveRetransTimeoutMsec + 999) / 1000;

static int gNumDataChangeBeforeCancellation;
static int gFinalStatus;
static SubscriptionHandler *gSubscriptionHandler = NULL;
static int gTimeBetweenDataChangeMsec = 0;
static bool gIsMutualSubscription = true;
static bool gEnableDataFlip = true;
static bool gMutualSubscriptionEstablished = false;
static bool gOnewaySubscriptionEstablished = false;
static bool gEvaluateSuccessIteration = false;
static bool gCleanStatus = true;
static bool gTestCase_TestOversizeTrait2DumpFlip = true;
static nl::Weave::WRMPConfig gWRMPConfig = { kWRMPInitialRetransTimeoutMsec, kWRMPActiveRetransTimeoutMsec, kWRMPAckTimeoutMsec, kWRMPMaxRetrans };

static nlDEFINE_ALIGNED_VAR(sTestGroupKeyStore, sizeof(TestGroupKeyStore), void*);

struct VersionNode
{
    uint64_t versionInfo;
    VersionNode * next;
};


class WdmInitiatorState
{
public:
    int mDataflipCount;
    int mClientStateCount;
    int mPublisherStateCount;
    void init(void)
    {
        mDataflipCount = 0;
        mClientStateCount = 1;
        mPublisherStateCount = 1;
    }
};

static WdmInitiatorState gInitiatorState;

namespace nl {
namespace Weave {
namespace Profiles {
namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {
class MockWdmSubscriptionInitiatorImpl: public MockWdmSubscriptionInitiator
{
public:
    MockWdmSubscriptionInitiatorImpl();

    virtual WEAVE_ERROR Init (nl::Weave::WeaveExchangeManager *aExchangeMgr,
                              uint32_t aKeyId,
                              uint32_t aTestSecurityMode,
                              const MockWdmNodeOptions &aConfig);

    virtual WEAVE_ERROR StartTesting(const uint64_t aPublisherNodeId, const uint16_t aSubnetId);
    virtual int32_t GetNumFaultInjectionEventsAvailable(void);
    void PrintVersionsLog();
    void ClearDataSinkState(void);
    void Cleanup(void);

private:
    nl::Weave::WeaveExchangeManager *mExchangeMgr;
    nl::Weave::Binding * mBinding;

    uint64_t mPublisherNodeId;
    uint16_t mPublisherSubnetId;

    static bool mClearDataSink;
    int mTestCaseId;
    int mTestSecurityMode;
    uint32_t mKeyId;
    bool mUseTCP;

    TraitPath mTraitPaths[4];
    VersionedTraitPath mVersionedTraitPaths[4];
    uint32_t mNumPaths;

    bool mEnableRetry;
    bool mWillRetry;

    // publisher side
    SingleResourceSourceTraitCatalog mSourceCatalog;
    SingleResourceSourceTraitCatalog::CatalogItem mSourceCatalogStore[4];
    nl::Weave::Profiles::DataManagement_Current::TraitSchemaEngine::IGetDataDelegate* mSinkAddressList[9];

    // source traits
    LocaleCapabilitiesTraitDataSource mLocaleCapabilitiesDataSource;
    TestATraitDataSource mTestATraitDataSource0;
    TestATraitDataSource mTestATraitDataSource1;
    TestBTraitDataSource mTestBTraitDataSource;
    TestBLargeTraitDataSource mTestBLargeTraitDataSource;

    static void ClearDataSinkIterator(void *aTraitInstance, TraitDataHandle aHandle, void *aContext);

    static void EngineEventCallback (void * const aAppState, SubscriptionEngine::EventID aEvent,
        const SubscriptionEngine::InEventParam & aInParam, SubscriptionEngine::OutEventParam & aOutParam);

    static void PublisherEventCallback (void * const aAppState,
        SubscriptionHandler::EventID aEvent, const SubscriptionHandler::InEventParam & aInParam,
        SubscriptionHandler::OutEventParam & aOutParam);

    // client side
    SingleResourceSinkTraitCatalog mSinkCatalog;
    SingleResourceSinkTraitCatalog::CatalogItem mSinkCatalogStore[9];

    // sink traits
#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    LocaleSettingsTraitUpdatableDataSink mLocaleSettingsTraitUpdatableDataSink;
    TestATraitUpdatableDataSink mTestATraitUpdatableDataSink0;
    TestATraitUpdatableDataSink mTestATraitUpdatableDataSink1;
    TestBTraitUpdatableDataSink mTestBTraitUpdatableDataSink;

    MockWdmNodeOptions::WdmUpdateMutation mUpdateMutation;
    MockWdmNodeOptions::WdmUpdateConditionality mUpdateConditionality;
    MockWdmNodeOptions::WdmUpdateTiming mUpdateTiming;
    uint32_t mUpdateNumTraits;
    uint32_t mUpdateMutationCounter;
    uint32_t mUpdateNumMutations;
    uint32_t mUpdateNumRepeatedMutations;
    bool     mUpdateDiscardOnError;
    uint32_t mUpdateSameMutationCounter;
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE

    BoltLockSettingTraitDataSink mBoltLockSettingsTraitDataSink;
    TestATraitDataSink mTestATraitDataSink0;
    LocaleSettingsTraitDataSink mLocaleSettingsTraitDataSink;
    TestATraitDataSink mTestATraitDataSink1;
    TestBTraitDataSink mTestBTraitDataSink;

    TestApplicationKeysTraitDataSink mApplicationKeysTraitDataSink;

    enum
    {
        kTestATraitSink0Index = 0,
        kTestATraitSink1Index,
        kTestBTraitSinkIndex,
        kLocaleSettingsSinkIndex,
        kBoltLockSettingTraitSinkIndex,
        kApplicationKeysTraitSinkIndex,

        kLocaleCapabilitiesSourceIndex,
        kTestATraitSource0Index,
        kTestATraitSource1Index,
        kTestBTraitSourceIndex,
        kTestBLargeTraitSourceIndex,
        kMaxNumTraitHandles,
    };

    enum
    {
        kClientCancel = 0,
        kPublisherCancel,
        kClientAbort,
        kPublisherAbort,
        kIdle
    };

    TraitDataHandle mTraitHandleSet[kMaxNumTraitHandles];

    enum
    {
        // subscribe LocaleSettings, TestA(two instances) and TestB traits in initiator
        // publish TestA(two instances) and TestB traits in initiator
        kTestCase_TestTrait = 1,

        // subscribe Locale Setting, ApplicationKeys traits in initiator
        // publish Locale Capabilities traits in responder
        kTestCase_IntegrationTrait = 2,

        //Reject Incoming subscribe request
        kTestCase_RejectIncomingSubscribeRequest    = 3,

        // subscribe oversize TestB, TestA(two instances) traits and LocaleSettings in initiator
        // publish TestA(two instances) and oversize TestB traits in initiator
        kTestCase_TestOversizeTrait1 = 4,

        // subscribe oversize LocaleSettings, TestB, and TestA(two instances) traits in initiator
        // publish TestA(two instances) and oversize TestB traits in initiator
        kTestCase_TestOversizeTrait2 = 5,

        kTestCase_CompatibleVersionedRequest = 6,

        kTestCase_ForwardCompatibleVersionedRequest = 7,

        kTestCase_IncompatibleVersionedRequest = 8,

        kTestCase_IncompatibleVersionedCommandRequest = 9,

        kTestCase_TestUpdatableTraits = 10,
    };

    enum
    {
        kMonitorCurrentStateCnt = 160,
        kMonitorCurrentStateInterval = 120 //msec
    };

    VersionNode mTraitVersionSet[kMaxNumTraitHandles];

    SubscriptionClient * mSubscriptionClient;

    void AddNewVersion (int aTraitDataSinkIndex);

    void DumpClientTraitChecksum(int TraitDataSinkIndex);
    void DumpClientTraits(void);

    void DumpPublisherTraitChecksum(int TraitDataSounceIndex);
    void DumpPublisherTraits(void);

    WEAVE_ERROR PrepareBinding();

    static void ClientEventCallback (void * const aAppState, SubscriptionClient::EventID aEvent,
        const SubscriptionClient::InEventParam & aInParam, SubscriptionClient::OutEventParam & aOutParam);

    static void BindingEventCallback (void * const apAppState, const nl::Weave::Binding::EventType aEvent,
        const nl::Weave::Binding::InEventParam & aInParam, nl::Weave::Binding::OutEventParam & aOutParam);

    static void HandleClientComplete(void *aAppState);

    static void HandlePublisherComplete();

    static void HandlePublisherRelease();

    static void HandleDataFlipTimeout (nl::Weave::System::Layer *aSystemLayer, void *aAppState, nl::Weave::System::Error aErr);
#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    static void HandleMutationTimeout (nl::Weave::System::Layer *aSystemLayer, void *aAppState, nl::Weave::System::Error aErr);
    WEAVE_ERROR ApplyWdmUpdateMutations();
#endif

    static void MonitorPublisherCurrentState (nl::Weave::System::Layer* aSystemLayer, void *aAppState, INET_ERROR aErr);

    static void MonitorClientCurrentState (nl::Weave::System::Layer* aSystemLayer, void *aAppState, INET_ERROR aErr);
};


bool MockWdmSubscriptionInitiatorImpl::mClearDataSink = false;

MockWdmSubscriptionInitiatorImpl::MockWdmSubscriptionInitiatorImpl() :
    mSourceCatalog(ResourceIdentifier(ResourceIdentifier::SELF_NODE_ID), mSourceCatalogStore, sizeof(mSourceCatalogStore) / sizeof(mSourceCatalogStore[0])),
    mSinkCatalog(ResourceIdentifier(ResourceIdentifier::SELF_NODE_ID), mSinkCatalogStore, sizeof(mSinkCatalogStore) / sizeof(mSinkCatalogStore[0]))
{
}

int32_t MockWdmSubscriptionInitiatorImpl::GetNumFaultInjectionEventsAvailable(void)
{
    int32_t retval = 0;

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    if (mSubscriptionClient && mSubscriptionClient->IsUpdateInFlight())
    {
        retval = 1;
    }
#endif

    return retval;

}

WEAVE_ERROR MockWdmSubscriptionInitiatorImpl::Init(
        nl::Weave::WeaveExchangeManager *aExchangeMgr,
        uint32_t aKeyId,
        uint32_t aTestSecurityMode,
        const MockWdmNodeOptions &aConfig)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    gIsMutualSubscription = aConfig.mEnableMutualSubscription;

    WeaveLogDetail(DataManagement, "Test Case ID: %s", (aConfig.mTestCaseId == NULL) ? "NULL" : aConfig.mTestCaseId);

    if (NULL != aConfig.mNumDataChangeBeforeCancellation)
    {
        gNumDataChangeBeforeCancellation = atoi(aConfig.mNumDataChangeBeforeCancellation);
    }
    else
    {
        gNumDataChangeBeforeCancellation = -1;
    }

    if (NULL != aConfig.mFinalStatus)
    {
        gFinalStatus = atoi(aConfig.mFinalStatus);
    }
    else
    {
        gFinalStatus = 0;
    }

    if (NULL != aConfig.mTimeBetweenDataChangeMsec)
    {
        gTimeBetweenDataChangeMsec = atoi(aConfig.mTimeBetweenDataChangeMsec);
    }
    else
    {
        gTimeBetweenDataChangeMsec = 15000;
    }

    if (NULL != aConfig.mTimeBetweenLivenessCheckSec)
    {
        gMinimumTimeBetweenLivenessCheckSec = atoi(aConfig.mTimeBetweenLivenessCheckSec);
    }
    else
    {
        gMinimumTimeBetweenLivenessCheckSec = 30;
    }

    gEnableDataFlip = aConfig.mEnableDataFlip;

    printf("aTestCaseId = %s\n", aConfig.mTestCaseId);

    if (NULL != aConfig.mTestCaseId)
    {
        mTestCaseId = atoi(aConfig.mTestCaseId);
    }
    else
    {
        mTestCaseId = kTestCase_TestTrait;
    }

    mUseTCP = aConfig.mUseTCP;

    mTestSecurityMode = aTestSecurityMode;

    mKeyId = aKeyId;

    mTestATraitDataSource0.mTraitTestSet = 0;

    mTestATraitDataSource1.mTraitTestSet = 0;

    if (aConfig.mEnableDictionaryTest)
    {
        mTestATraitDataSource1.mTraitTestSet = 1;
    }

    mEnableRetry = aConfig.mEnableRetry;

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    mUpdateMutation = aConfig.mWdmUpdateMutation;
    mUpdateConditionality = aConfig.mWdmUpdateConditionality;
    mUpdateTiming = aConfig.mWdmUpdateTiming;
    mUpdateNumTraits = aConfig.mWdmUpdateNumberOfTraits;
    mUpdateMutationCounter = 0;
    mUpdateNumMutations = aConfig.mWdmUpdateNumberOfMutations;
    mUpdateNumRepeatedMutations = aConfig.mWdmUpdateNumberOfRepeatedMutations;
    mUpdateDiscardOnError = aConfig.mWdmUpdateDiscardOnError;
    mUpdateSameMutationCounter = 0;
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE

    switch (mTestCaseId)
    {
    case kTestCase_TestUpdatableTraits:
#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
        mSinkCatalog.Add(0, &mTestATraitUpdatableDataSink0, mTraitHandleSet[kTestATraitSink0Index]);
        mSinkCatalog.Add(1, &mTestATraitUpdatableDataSink1, mTraitHandleSet[kTestATraitSink1Index]);
        mSinkCatalog.Add(0, &mLocaleSettingsTraitUpdatableDataSink, mTraitHandleSet[kLocaleSettingsSinkIndex]);
        mSinkCatalog.Add(0, &mTestBTraitUpdatableDataSink, mTraitHandleSet[kTestBTraitSinkIndex]);
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE
        break;
    default:
        mSinkCatalog.Add(0, &mTestATraitDataSink0, mTraitHandleSet[kTestATraitSink0Index]);
        mSinkCatalog.Add(1, &mTestATraitDataSink1, mTraitHandleSet[kTestATraitSink1Index]);
        mSinkCatalog.Add(0, &mTestBTraitDataSink, mTraitHandleSet[kTestBTraitSinkIndex]);
        mSinkCatalog.Add(0, &mLocaleSettingsTraitDataSink, mTraitHandleSet[kLocaleSettingsSinkIndex]);
    }

    mSinkCatalog.Add(0, &mBoltLockSettingsTraitDataSink, mTraitHandleSet[kBoltLockSettingTraitSinkIndex]);
    mApplicationKeysTraitDataSink.SetGroupKeyStore(new (&sTestGroupKeyStore) TestGroupKeyStore());
    mSinkCatalog.Add(0, &mApplicationKeysTraitDataSink, mTraitHandleSet[kApplicationKeysTraitSinkIndex]);

    mSourceCatalog.Add(0, &mLocaleCapabilitiesDataSource, mTraitHandleSet[kLocaleCapabilitiesSourceIndex]);
    mSourceCatalog.Add(1, &mTestATraitDataSource0, mTraitHandleSet[kTestATraitSource0Index]);
    mSourceCatalog.Add(2, &mTestATraitDataSource1, mTraitHandleSet[kTestATraitSource1Index]);

    switch (mTestCaseId)
    {
    case kTestCase_TestOversizeTrait1:
    case kTestCase_TestOversizeTrait2:
         mSourceCatalog.Add(1, &mTestBLargeTraitDataSource, mTraitHandleSet[kTestBLargeTraitSourceIndex]);
         break;
    default:
        mSourceCatalog.Add(1, &mTestBTraitDataSource, mTraitHandleSet[kTestBTraitSourceIndex]);
        break;
    }

    switch (mTestCaseId)
    {
    case kTestCase_IntegrationTrait:
        WeaveLogDetail(DataManagement, "kTestCase_IntegrationTrait");
        break;

    case kTestCase_RejectIncomingSubscribeRequest:
        WeaveLogDetail(DataManagement, "kTestCase_RejectIncomingSubscribeRequest");
        break;

    case kTestCase_TestTrait:
        WeaveLogDetail(DataManagement, "kTestCase_TestTrait");
        break;

    case kTestCase_TestOversizeTrait1:
    case kTestCase_TestOversizeTrait2:
        WeaveLogDetail(DataManagement, "kTestCase_TestOversizeTrait %d", mTestCaseId);
        break;

    case kTestCase_CompatibleVersionedRequest:
        WeaveLogDetail(DataManagement, "kTestCase_CompatibleVersionedRequest");
        break;

    case kTestCase_ForwardCompatibleVersionedRequest:
        WeaveLogDetail(DataManagement, "kTestCase_ForwardCompatibleVersionedRequest");
        break;

    case kTestCase_IncompatibleVersionedRequest:
        WeaveLogDetail(DataManagement, "kTestCase_IncompatibleVersionedRequest");
        break;

    case kTestCase_TestUpdatableTraits:
        WeaveLogDetail(DataManagement, "kTestCase_TestUpdatableTraits");
        break;
    default:
        mTestCaseId = kTestCase_TestTrait;
        WeaveLogDetail(DataManagement, "kTestCase_TestTrait");
        break;
    }

    mExchangeMgr = aExchangeMgr;
    mBinding = NULL;

    mSubscriptionClient = NULL;

    // Note if you don't use publisher side, there is no need to initialize using this longer form
    err = SubscriptionEngine::GetInstance()->Init(mExchangeMgr, this, EngineEventCallback);
    SuccessOrExit(err);

    if (gIsMutualSubscription == true)
    {
        err = SubscriptionEngine::GetInstance()->EnablePublisher(NULL, &mSourceCatalog);
        SuccessOrExit(err);
    }

    mTraitVersionSet[kTestATraitSink0Index].versionInfo = mTestATraitDataSink0.GetVersion();
    mTraitVersionSet[kTestATraitSink0Index].next = NULL;
    mTraitVersionSet[kTestATraitSink1Index].versionInfo = mTestATraitDataSink1.GetVersion();
    mTraitVersionSet[kTestATraitSink1Index].next = NULL;
    mTraitVersionSet[kTestBTraitSinkIndex].versionInfo = mTestBTraitDataSink.GetVersion();
    mTraitVersionSet[kTestBTraitSinkIndex].next = NULL;
    mTraitVersionSet[kLocaleSettingsSinkIndex].versionInfo = mLocaleSettingsTraitDataSink.GetVersion();
    mTraitVersionSet[kLocaleSettingsSinkIndex].next = NULL;
    mTraitVersionSet[kBoltLockSettingTraitSinkIndex].versionInfo = mBoltLockSettingsTraitDataSink.GetVersion();
    mTraitVersionSet[kBoltLockSettingTraitSinkIndex].next = NULL;
    mTraitVersionSet[kApplicationKeysTraitSinkIndex].versionInfo = mApplicationKeysTraitDataSink.GetVersion();
    mTraitVersionSet[kApplicationKeysTraitSinkIndex].next = NULL;

    mSinkAddressList[kTestATraitSink0Index] = &mTestATraitDataSink0;
    mSinkAddressList[kTestATraitSink1Index] = &mTestATraitDataSink1;
    mSinkAddressList[kTestBTraitSinkIndex] = &mTestBTraitDataSink;
    mSinkAddressList[kLocaleSettingsSinkIndex] = &mLocaleSettingsTraitDataSink;
    mSinkAddressList[kBoltLockSettingTraitSinkIndex] = &mBoltLockSettingsTraitDataSink;
    mSinkAddressList[kApplicationKeysTraitSinkIndex] = &mApplicationKeysTraitDataSink;

exit:
    return err;
}

WEAVE_ERROR MockWdmSubscriptionInitiatorImpl::StartTesting(const uint64_t aPublisherNodeId, const uint16_t aSubnetId)
{
    gInitiatorState.init();
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    mPublisherNodeId = aPublisherNodeId;
    mPublisherSubnetId = aSubnetId;

    if (mBinding == NULL)
    {
        mBinding = mExchangeMgr->NewBinding(BindingEventCallback, this);
        VerifyOrExit(NULL != mBinding, err = WEAVE_ERROR_NO_MEMORY);
    }

    if (mSubscriptionClient == NULL)
    {
        err =  SubscriptionEngine::GetInstance()->NewClient(&mSubscriptionClient,
                mBinding,
                this,
                ClientEventCallback,
                &mSinkCatalog,
                kResponseTimeoutMsec * 2); // max num of msec between subscribe request and subscribe response
        SuccessOrExit(err);
    }

    // TODO: EVENT-DEMO
    // TODO: Fix this dummy observed event list
    /*
    SubscriptionClient::LastObservedEvent DummyObservedEvents[] =
    {
        {1, 2, 3},
        {4, 5, 6},
    };
    */

    switch (mTestCaseId)
    {
    case kTestCase_IntegrationTrait:
    case kTestCase_RejectIncomingSubscribeRequest:
        mTraitPaths[0].mTraitDataHandle = mTraitHandleSet[kLocaleSettingsSinkIndex];
        mTraitPaths[0].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[1].mTraitDataHandle = mTraitHandleSet[kApplicationKeysTraitSinkIndex];
        mTraitPaths[1].mPropertyPathHandle = kRootPropertyPathHandle;

        mNumPaths = 2;
        break;

    case kTestCase_TestTrait:
    case kTestCase_TestUpdatableTraits:
        mTraitPaths[0].mTraitDataHandle = mTraitHandleSet[kLocaleSettingsSinkIndex];
        mTraitPaths[0].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[1].mTraitDataHandle = mTraitHandleSet[kTestATraitSink0Index];
        mTraitPaths[1].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[2].mTraitDataHandle = mTraitHandleSet[kTestATraitSink1Index];
        mTraitPaths[2].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[3].mTraitDataHandle = mTraitHandleSet[kTestBTraitSinkIndex];
        mTraitPaths[3].mPropertyPathHandle = kRootPropertyPathHandle;

        mNumPaths = 4;
        break;

    case kTestCase_TestOversizeTrait1:
        mTraitPaths[0].mTraitDataHandle = mTraitHandleSet[kTestBTraitSinkIndex];
        mTraitPaths[0].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[1].mTraitDataHandle = mTraitHandleSet[kTestATraitSink0Index];
        mTraitPaths[1].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[2].mTraitDataHandle = mTraitHandleSet[kTestATraitSink1Index];
        mTraitPaths[2].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[3].mTraitDataHandle = mTraitHandleSet[kLocaleSettingsSinkIndex];
        mTraitPaths[3].mPropertyPathHandle = kRootPropertyPathHandle;

        mNumPaths = 4;
        break;

     case kTestCase_TestOversizeTrait2:
        mTraitPaths[0].mTraitDataHandle = mTraitHandleSet[kLocaleSettingsSinkIndex];
        mTraitPaths[0].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[1].mTraitDataHandle = mTraitHandleSet[kTestBTraitSinkIndex];
        mTraitPaths[1].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[2].mTraitDataHandle = mTraitHandleSet[kTestATraitSink0Index];
        mTraitPaths[2].mPropertyPathHandle = kRootPropertyPathHandle;

        mTraitPaths[3].mTraitDataHandle = mTraitHandleSet[kTestATraitSink1Index];
        mTraitPaths[3].mPropertyPathHandle = kRootPropertyPathHandle;

        mNumPaths = 4;
        break;

    case kTestCase_CompatibleVersionedRequest:
    case kTestCase_ForwardCompatibleVersionedRequest:
    case kTestCase_IncompatibleVersionedRequest:
        for (int i = 0; i < 4; i++) {
            if (mTestCaseId == kTestCase_CompatibleVersionedRequest) {
                mVersionedTraitPaths[i].mRequestedVersionRange.mMinVersion = 1;
                mVersionedTraitPaths[i].mRequestedVersionRange.mMaxVersion = 1;
            }
            else if (mTestCaseId == kTestCase_ForwardCompatibleVersionedRequest) {
                mVersionedTraitPaths[i].mRequestedVersionRange.mMinVersion = 1;
                mVersionedTraitPaths[i].mRequestedVersionRange.mMaxVersion = 4;
            }
            else if (mTestCaseId == kTestCase_IncompatibleVersionedRequest) {
                mVersionedTraitPaths[i].mRequestedVersionRange.mMinVersion = 2;
                mVersionedTraitPaths[i].mRequestedVersionRange.mMaxVersion = 4;
            }
        }

        mVersionedTraitPaths[0].mTraitDataHandle = mTraitHandleSet[kLocaleSettingsSinkIndex];
        mVersionedTraitPaths[0].mPropertyPathHandle = kRootPropertyPathHandle;

        mVersionedTraitPaths[1].mTraitDataHandle = mTraitHandleSet[kTestATraitSink0Index];
        mVersionedTraitPaths[1].mPropertyPathHandle = kRootPropertyPathHandle;

        mVersionedTraitPaths[2].mTraitDataHandle = mTraitHandleSet[kTestATraitSink1Index];
        mVersionedTraitPaths[2].mPropertyPathHandle = kRootPropertyPathHandle;

        mVersionedTraitPaths[3].mTraitDataHandle = mTraitHandleSet[kTestBTraitSinkIndex];
        mVersionedTraitPaths[3].mPropertyPathHandle = kRootPropertyPathHandle;

        mNumPaths = 4;
        break;

    default:
        mNumPaths = 0;
        break;
    }

    if (mEnableRetry)
    {
        mSubscriptionClient->EnableResubscribe(NULL);
    }

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
     if (mTestCaseId == kTestCase_TestUpdatableTraits)
     {
         switch (mUpdateTiming)
         {
         case MockWdmNodeOptions::kTiming_BeforeSub:
             gInitiatorState.mDataflipCount++;
         case MockWdmNodeOptions::kTiming_NoSub:
             (void)ApplyWdmUpdateMutations();
         default:
              WeaveLogDetail(DataManagement, "update timing mode is %d", mUpdateTiming);
              break;
         }
     }
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    if (mUpdateTiming != MockWdmNodeOptions::kTiming_NoSub)
    {
#endif
        mSubscriptionClient->InitiateSubscription();

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    }
#endif

exit:
    WeaveLogFunctError(err);
    if (err != WEAVE_NO_ERROR && mBinding != NULL)
    {
        mBinding->Release();
        mBinding = NULL;
    }
    return err;
}

WEAVE_ERROR MockWdmSubscriptionInitiatorImpl::PrepareBinding()
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    Binding::Configuration bindingConfig = mBinding->BeginConfiguration()
        .Target_NodeId(mPublisherNodeId) // TODO: aPublisherNodeId
        .Exchange_ResponseTimeoutMsec(kResponseTimeoutMsec);

    if (mUseTCP)
    {
        bindingConfig.Transport_TCP();
    }
    else
    {
        bindingConfig.Transport_UDP_WRM()
            .Transport_DefaultWRMPConfig(gWRMPConfig);
    }

    if (nl::Weave::kWeaveSubnetId_NotSpecified != mPublisherSubnetId)
    {
        bindingConfig.TargetAddress_WeaveFabric(mPublisherSubnetId);
    }

    switch (mTestSecurityMode)
    {
    case WeaveSecurityMode::kCASE:
        WeaveLogDetail(DataManagement, "security mode is kWdmSecurity_CASE");
        bindingConfig.Security_SharedCASESession();
        break;

    case WeaveSecurityMode::kGroupEnc:
        WeaveLogDetail(DataManagement, "security mode is kWdmSecurity_GroupKey");
        if (mKeyId == WeaveKeyId::kNone)
        {
            WeaveLogDetail(DataManagement, "Please specify a group encryption key id using the --group-enc-... options.\n");
            err = WEAVE_ERROR_INVALID_KEY_ID;
            SuccessOrExit(err);
        }
        bindingConfig.Security_Key(mKeyId);
        //.Security_Key(0x5536);
        //.Security_Key(0x4436);
        break;

    case WeaveSecurityMode::kNone:
        bindingConfig.Security_None();
        break;

    default:
        WeaveLogDetail(DataManagement, "security mode is not supported");
        err = WEAVE_ERROR_UNSUPPORTED_AUTH_MODE;
        SuccessOrExit(err);
    }

    err = bindingConfig.PrepareBinding();
    SuccessOrExit(err);

exit:
    WeaveLogFunctError(err);
    return err;
}

void MockWdmSubscriptionInitiatorImpl::BindingEventCallback (void * const apAppState, const nl::Weave::Binding::EventType aEvent,
    const nl::Weave::Binding::InEventParam & aInParam, nl::Weave::Binding::OutEventParam & aOutParam)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    WeaveLogDetail(DataManagement, "%s: Event(%d)", __func__, aEvent);

    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(apAppState);

    VerifyOrDie(aInParam.Source != NULL);
    VerifyOrDie(aEvent == nl::Weave::Binding::kEvent_DefaultCheck || initiator->mBinding == aInParam.Source);

    switch (aEvent)
    {
    case nl::Weave::Binding::kEvent_PrepareRequested:
        WeaveLogDetail(DataManagement, "kEvent_PrepareRequested");
        err = initiator->PrepareBinding();
        SuccessOrExit(err);
        break;

    case nl::Weave::Binding::kEvent_PrepareFailed:
        // Don't fail; let the protocol retry.
        //err = aInParam.PrepareFailed.Reason;
        WeaveLogDetail(DataManagement, "kEvent_PrepareFailed: reason %s", ::nl::ErrorStr(aInParam.PrepareFailed.Reason));
        break;

    case nl::Weave::Binding::kEvent_BindingFailed:
        // Don't fail; let the protocol retry.
        //err = aInParam.BindingFailed.Reason;
        WeaveLogDetail(DataManagement, "kEvent_BindingFailed: reason %s", ::nl::ErrorStr(aInParam.PrepareFailed.Reason));
        break;

    case nl::Weave::Binding::kEvent_BindingReady:
        WeaveLogDetail(DataManagement, "kEvent_BindingReady");
        break;
    case nl::Weave::Binding::kEvent_DefaultCheck:
        WeaveLogDetail(DataManagement, "kEvent_DefaultCheck");
        // fall through
    default:
        nl::Weave::Binding::DefaultEventHandler(apAppState, aEvent, aInParam, aOutParam);
    }

exit:
    if (err != WEAVE_NO_ERROR)
    {
        if (NULL != initiator->onError)
        {
            initiator->onError();
        }
        initiator->mBinding->Release();
        initiator->mBinding = NULL;
        if (initiator->mSubscriptionClient)
        {
            initiator->mSubscriptionClient->Free();
            initiator->mSubscriptionClient = NULL;
        }
    }
    WeaveLogFunctError(err);
}

void MockWdmSubscriptionInitiatorImpl::DumpPublisherTraitChecksum(int inTraitDataSourceIndex)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TraitDataSource *dataSource;
    err = mSourceCatalog.Locate(mTraitHandleSet[inTraitDataSourceIndex], &dataSource);
    SuccessOrExit(err);

    ::DumpPublisherTraitChecksum(dataSource);
exit:
    WeaveLogFunctError(err);
}

void MockWdmSubscriptionInitiatorImpl::DumpClientTraitChecksum(int inTraitDataSinkIndex)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TraitDataSink *dataSink;
    TraitSchemaEngine::IGetDataDelegate *dataSource;

    dataSource = mSinkAddressList[inTraitDataSinkIndex];
    err = mSinkCatalog.Locate(mTraitHandleSet[inTraitDataSinkIndex], &dataSink);
    SuccessOrExit(err);

    ::DumpClientTraitChecksum(dataSink->GetSchemaEngine(), dataSource);
exit:
    WeaveLogFunctError(err);
}

void MockWdmSubscriptionInitiatorImpl::DumpClientTraits(void)
{
    switch (mTestCaseId)
    {
        case kTestCase_IntegrationTrait:
        case kTestCase_RejectIncomingSubscribeRequest:
            DumpClientTraitChecksum(kLocaleSettingsSinkIndex);
            DumpClientTraitChecksum(kApplicationKeysTraitSinkIndex);
            break;
        case kTestCase_TestTrait:
            DumpClientTraitChecksum(kTestATraitSink0Index);
            DumpClientTraitChecksum(kTestATraitSink1Index);
            DumpClientTraitChecksum(kTestBTraitSinkIndex);
            DumpClientTraitChecksum(kLocaleSettingsSinkIndex);
            break;
        case kTestCase_TestUpdatableTraits:
            break;
        case kTestCase_TestOversizeTrait1:
            DumpClientTraitChecksum(kTestATraitSink0Index);
            DumpClientTraitChecksum(kTestATraitSink1Index);
            DumpClientTraitChecksum(kLocaleSettingsSinkIndex);
            break;
        case kTestCase_TestOversizeTrait2:
            if (gTestCase_TestOversizeTrait2DumpFlip)
            {
                DumpClientTraitChecksum(kLocaleSettingsSinkIndex);
            }
            else
            {
                DumpClientTraitChecksum(kTestATraitSink0Index);
                DumpClientTraitChecksum(kTestATraitSink1Index);
            }
            break;
    }
}
void MockWdmSubscriptionInitiatorImpl::DumpPublisherTraits(void)
{
    switch (mTestCaseId)
    {
        case kTestCase_IntegrationTrait:
        case kTestCase_RejectIncomingSubscribeRequest:
            DumpPublisherTraitChecksum(kLocaleCapabilitiesSourceIndex);
            break;
        case kTestCase_TestTrait:
            DumpPublisherTraitChecksum(kTestATraitSource0Index);
            DumpPublisherTraitChecksum(kTestATraitSource1Index);
            DumpPublisherTraitChecksum(kTestBTraitSourceIndex);
            break;
        case kTestCase_TestOversizeTrait1:
        case kTestCase_TestOversizeTrait2:
            DumpPublisherTraitChecksum(kTestATraitSource0Index);
            DumpPublisherTraitChecksum(kTestATraitSource1Index);
            break;
    }
}

void MockWdmSubscriptionInitiatorImpl::EngineEventCallback (void * const aAppState,
    SubscriptionEngine::EventID aEvent,
    const SubscriptionEngine::InEventParam & aInParam, SubscriptionEngine::OutEventParam & aOutParam)
{
    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(aAppState);
    switch (aEvent)
    {
    case SubscriptionEngine::kEvent_OnIncomingSubscribeRequest:
        WeaveLogDetail(DataManagement, "Engine->kEvent_OnIncomingSubscribeRequest peer = 0x%" PRIX64, aInParam.mIncomingSubscribeRequest.mEC->PeerNodeId);
        aOutParam.mIncomingSubscribeRequest.mHandlerAppState = initiator;
        aOutParam.mIncomingSubscribeRequest.mHandlerEventCallback = MockWdmSubscriptionInitiatorImpl::PublisherEventCallback;
        aOutParam.mIncomingSubscribeRequest.mRejectRequest = false;

        aInParam.mIncomingSubscribeRequest.mBinding->SetDefaultResponseTimeout(kResponseTimeoutMsec);
        aInParam.mIncomingSubscribeRequest.mBinding->SetDefaultWRMPConfig(gWRMPConfig);

        break;
    default:
        SubscriptionEngine::DefaultEventHandler(aEvent, aInParam, aOutParam);
        break;
    }
}

void MockWdmSubscriptionInitiatorImpl::AddNewVersion(int aTraitDataSinkIndex)
{
    VersionNode * curr = &mTraitVersionSet[aTraitDataSinkIndex];
    while (curr->next != NULL)
    {
        curr = curr->next;
    }

    if (curr->versionInfo != mSinkCatalogStore[aTraitDataSinkIndex].mItem->GetVersion())
    {
        VersionNode * updatingVersion = (VersionNode *)malloc(sizeof(VersionNode));
        WeaveLogDetail(DataManagement, "Trait %u version is changed %" PRIu64 " ---> %" PRIu64, aTraitDataSinkIndex, curr->versionInfo, mSinkCatalogStore[aTraitDataSinkIndex].mItem->GetVersion());
        updatingVersion->versionInfo = mSinkCatalogStore[aTraitDataSinkIndex].mItem->GetVersion();
        updatingVersion->next = NULL;
        curr->next = updatingVersion;
    }
}

void MockWdmSubscriptionInitiatorImpl::Cleanup()
{
    if (NULL != mSubscriptionClient)
    {
        mSubscriptionClient->Free();
        mSubscriptionClient = NULL;
    }

    if (NULL != mBinding)
    {
        mBinding->Release();
        mBinding = NULL;
    }
}

void MockWdmSubscriptionInitiatorImpl::PrintVersionsLog()
{
    for (int i = 0; i< kMaxNumTraitHandles; i++)
    {
        VersionNode * pre = &mTraitVersionSet[i];
        VersionNode * curr = mTraitVersionSet[i].next;

        printf("Initiator's trait %u versions log is : %" PRIu64, i, pre->versionInfo);
        while (curr != NULL)
        {
            pre = curr;
            curr = curr->next;
            printf(" ==> %" PRIu64, pre->versionInfo);
        }
        printf("\n");
    }
}

void MockWdmSubscriptionInitiatorImpl::ClearDataSinkIterator(void *aTraitInstance, TraitDataHandle aHandle, void *aContext)
{
    MockTraitDataSink *traitInstance = static_cast<MockTraitDataSink *>(aTraitInstance);
    traitInstance->ResetDataSink();
}

void MockWdmSubscriptionInitiatorImpl::ClearDataSinkState(void)
{
    mSinkCatalog.Iterate(MockWdmSubscriptionInitiatorImpl::ClearDataSinkIterator, NULL);
    mClearDataSink = true;
}

void MockWdmSubscriptionInitiatorImpl::ClientEventCallback (void * const aAppState, SubscriptionClient::EventID aEvent,
    const SubscriptionClient::InEventParam & aInParam, SubscriptionClient::OutEventParam & aOutParam)
{
    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(aAppState);

    switch (aEvent)
    {
    case SubscriptionClient::kEvent_OnExchangeStart:
        WeaveLogDetail(DataManagement, "Client->kEvent_OnExchangeStart");
        break;
    case SubscriptionClient::kEvent_OnSubscribeRequestPrepareNeeded:
        WeaveLogDetail(DataManagement, "Client->kEvent_OnSubscribeRequestPrepareNeeded");
        if (initiator->mTestCaseId >= kTestCase_CompatibleVersionedRequest && initiator->mTestCaseId <= kTestCase_IncompatibleVersionedRequest) {
            aOutParam.mSubscribeRequestPrepareNeeded.mVersionedPathList = initiator->mVersionedTraitPaths;
        }
        else {
            aOutParam.mSubscribeRequestPrepareNeeded.mPathList = initiator->mTraitPaths;
        }

        aOutParam.mSubscribeRequestPrepareNeeded.mPathListSize = initiator->mNumPaths;
        aOutParam.mSubscribeRequestPrepareNeeded.mNeedAllEvents = true;
        aOutParam.mSubscribeRequestPrepareNeeded.mLastObservedEventList = NULL;
        aOutParam.mSubscribeRequestPrepareNeeded.mLastObservedEventListSize = 0;
        aOutParam.mSubscribeRequestPrepareNeeded.mTimeoutSecMin = gMinimumTimeBetweenLivenessCheckSec;
        aOutParam.mSubscribeRequestPrepareNeeded.mTimeoutSecMax = 3600;
        break;

    case SubscriptionClient::kEvent_OnSubscriptionEstablished:
        WeaveLogDetail(DataManagement, "Client->kEvent_OnSubscriptionEstablished");
        WeaveLogDetail(DataManagement, "Liveness Timeout: %u msec", aInParam.mSubscriptionEstablished.mClient->GetLivenessTimeoutMsec());
        if (gIsMutualSubscription == false)
        {
            gOnewaySubscriptionEstablished = true;

            if (gNumDataChangeBeforeCancellation != 0)
            {
                initiator->mExchangeMgr->MessageLayer->SystemLayer->StartTimer(gTimeBetweenDataChangeMsec, HandleDataFlipTimeout, initiator);
            }
            else
            {
                if (gFinalStatus != kIdle)
                {
                    switch (gFinalStatus)
                    {
                    case kPublisherCancel:
                    case kPublisherAbort:
                        initiator->mExchangeMgr->MessageLayer->SystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorPublisherCurrentState, initiator);
                        break;
                    case kClientCancel:
                    case kClientAbort:
                        initiator->mExchangeMgr->MessageLayer->SystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorClientCurrentState, initiator);
                        break;
                    default:
                        break;
                    }
                }
            }
        }
        break;
    case SubscriptionClient::kEvent_OnNotificationRequest:
        WeaveLogDetail(DataManagement, "Client->kEvent_OnNotificationRequest");
        break;
    case SubscriptionClient::kEvent_OnNotificationProcessed:
        WeaveLogDetail(DataManagement, "Client->kEvent_OnNotificationProcessed");

        switch (initiator->mTestCaseId)
        {
        case kTestCase_IntegrationTrait:
        case kTestCase_RejectIncomingSubscribeRequest:
            initiator->AddNewVersion(initiator->kLocaleSettingsSinkIndex);
            initiator->AddNewVersion(initiator->kApplicationKeysTraitSinkIndex);
            break;
        case kTestCase_TestTrait:
            initiator->AddNewVersion(initiator->kTestATraitSink0Index);
            initiator->AddNewVersion(initiator->kTestATraitSink1Index);
            initiator->AddNewVersion(initiator->kTestBTraitSinkIndex);
            initiator->AddNewVersion(initiator->kLocaleSettingsSinkIndex);
            break;
        case kTestCase_TestUpdatableTraits:
            break;
        case kTestCase_TestOversizeTrait1:
            initiator->AddNewVersion(initiator->kTestATraitSink0Index);
            initiator->AddNewVersion(initiator->kTestATraitSink1Index);
            initiator->AddNewVersion(initiator->kLocaleSettingsSinkIndex);
            break;
       case kTestCase_TestOversizeTrait2:
            if (gTestCase_TestOversizeTrait2DumpFlip)
            {
                initiator->AddNewVersion(initiator->kLocaleSettingsSinkIndex);
            }
            else
            {
                initiator->AddNewVersion(initiator->kTestATraitSink0Index);
                initiator->AddNewVersion(initiator->kTestATraitSink1Index);
            }
            break;
        }

        initiator->DumpClientTraits();

        if (initiator->mTestCaseId == kTestCase_TestOversizeTrait2)
        {
            gTestCase_TestOversizeTrait2DumpFlip = !gTestCase_TestOversizeTrait2DumpFlip;
        }

        break;
    case SubscriptionClient::kEvent_OnSubscriptionTerminated:
        WeaveLogDetail(DataManagement, "Client->kEvent_OnSubscriptionTerminated. peer = 0x%" PRIX64 ", %s: %s",
                aInParam.mSubscriptionTerminated.mClient->GetPeerNodeId(),
                (aInParam.mSubscriptionTerminated.mIsStatusCodeValid) ? "Status Report" : "Error",
                (aInParam.mSubscriptionTerminated.mIsStatusCodeValid)
                    ? ::nl::StatusReportStr(aInParam.mSubscriptionTerminated.mStatusProfileId, aInParam.mSubscriptionTerminated.mStatusCode)
                    : ::nl::ErrorStr(aInParam.mSubscriptionTerminated.mReason));

        initiator->mWillRetry = aInParam.mSubscriptionTerminated.mWillRetry;
        WeaveLogDetail(DataManagement, "mWillRetry is %s", aInParam.mSubscriptionTerminated.mWillRetry ? "true" : "false");

        switch (gFinalStatus)
        {
        case kPublisherCancel:
        case kPublisherAbort:
            initiator->mExchangeMgr->MessageLayer->SystemLayer->CancelTimer(MonitorPublisherCurrentState, initiator);
            break;
        case kClientCancel:
        case kClientAbort:
            initiator->mExchangeMgr->MessageLayer->SystemLayer->CancelTimer(MonitorClientCurrentState, initiator);
            break;
        case kIdle:
        default:
            break;
        }

        if (initiator->mEnableRetry == false || initiator->mWillRetry == false)
        {
            gInitiatorState.mDataflipCount = 0;

            if (gEvaluateSuccessIteration == true)
            {
                WeaveLogDetail(DataManagement, "Mutual: Good Iteration");
                gEvaluateSuccessIteration = false;
            }
            if (gNumDataChangeBeforeCancellation != 0)
            {
                initiator->mExchangeMgr->MessageLayer->SystemLayer->CancelTimer(HandleDataFlipTimeout, initiator);
            }
            initiator->onCompleteTest();
        }
        break;
#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    case SubscriptionClient::kEvent_OnUpdateComplete:
        if ((aInParam.mUpdateComplete.mReason == WEAVE_NO_ERROR) && (nl::Weave::Profiles::kWeaveProfile_Common == aInParam.mUpdateComplete.mStatusProfileId) && (nl::Weave::Profiles::Common::kStatus_Success == aInParam.mUpdateComplete.mStatusCode))
        {
            WeaveLogDetail(DataManagement, "Update: path result: success");
        }
        else
        {
            WeaveLogDetail(DataManagement, "Update: path failed: %s, %s, tdh %" PRIu16", will %sretry",
                           ErrorStr(aInParam.mUpdateComplete.mReason),
                           nl::StatusReportStr(aInParam.mUpdateComplete.mStatusProfileId, aInParam.mUpdateComplete.mStatusCode),
                           aInParam.mUpdateComplete.mTraitDataHandle,
                           aInParam.mUpdateComplete.mWillRetry ? "" : "not ");

            if (initiator->mUpdateDiscardOnError)
            {
                initiator->mSubscriptionClient->DiscardUpdates();
            }
        }
        break;
    case SubscriptionClient::kEvent_OnNoMorePendingUpdates:
        WeaveLogDetail(DataManagement, "Update: no more pending updates");
        break;
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE

    default:
        SubscriptionClient::DefaultEventHandler(aEvent, aInParam, aOutParam);
        break;
    }
}

void MockWdmSubscriptionInitiatorImpl::PublisherEventCallback (void * const aAppState,
        SubscriptionHandler::EventID aEvent, const SubscriptionHandler::InEventParam & aInParam, SubscriptionHandler::OutEventParam & aOutParam)
{
    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(aAppState);
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    switch (aEvent)
    {
    case SubscriptionHandler::kEvent_OnSubscribeRequestParsed:
        WeaveLogDetail(DataManagement, "Publisher->kEvent_OnSubscribeRequestParsed");

        // ideally this number should be set to something for cloud service, and something else for everyone else
        // we can potentially copy this from the client side, but it would take considerable amount of code to be generic enough
        // setting to some constant here seems to be easier

        aInParam.mSubscribeRequestParsed.mHandler->GetBinding()->SetDefaultResponseTimeout(kResponseTimeoutMsec);
        aInParam.mSubscribeRequestParsed.mHandler->GetBinding()->SetDefaultWRMPConfig(gWRMPConfig);

        if (NULL != initiator->mSubscriptionClient)
        {
            if (aInParam.mSubscribeRequestParsed.mIsSubscriptionIdValid)
            {
                uint64_t subscriptionId;
                err = initiator->mSubscriptionClient->GetSubscriptionId(&subscriptionId);
                SuccessOrExit(err);

                // subscription ID is largely peer-specific
                if ((aInParam.mSubscribeRequestParsed.mEC->PeerNodeId == initiator->mBinding->GetPeerNodeId()) &&
                    (aInParam.mSubscribeRequestParsed.mSubscriptionId == subscriptionId))
                {
                    WeaveLogDetail(DataManagement, "Request for mutual subscription found");
                }
            }
        }

        // AcceptSubscribeRequest and EndSubscription may be used either sync or async, to move the state machine forward
        aInParam.mSubscribeRequestParsed.mHandler->AcceptSubscribeRequest();

        break;

    case SubscriptionHandler::kEvent_OnExchangeStart:
        WeaveLogDetail(DataManagement, "Publisher->kEvent_OnExchangeStart");
        break;

    case SubscriptionHandler::kEvent_OnSubscriptionEstablished:
        if (true == mClearDataSink || true == gCleanStatus)
        {
            initiator->DumpPublisherTraits();
            gCleanStatus = false;
        }

        WeaveLogDetail(DataManagement, "Publisher->kEvent_OnSubscriptionEstablished");
        gMutualSubscriptionEstablished = true;
        gSubscriptionHandler = aInParam.mSubscriptionEstablished.mHandler;
        if (gNumDataChangeBeforeCancellation != 0)
        {
            initiator->mExchangeMgr->MessageLayer->SystemLayer->StartTimer(gTimeBetweenDataChangeMsec, HandleDataFlipTimeout, initiator);
        }
        else
        {
            if (gFinalStatus != kIdle)
            {
                switch (gFinalStatus)
                {
                case kPublisherCancel:
                case kPublisherAbort:
                    initiator->mExchangeMgr->MessageLayer->SystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorPublisherCurrentState, initiator);
                    break;
                case kClientCancel:
                case kClientAbort:
                    initiator->mExchangeMgr->MessageLayer->SystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorClientCurrentState, initiator);
                    break;
                default:
                    break;
                }
            }
        }
        break;

    case SubscriptionHandler::kEvent_OnSubscriptionTerminated:
        WeaveLogDetail(DataManagement, "Pub: kEvent_OnSubscriptionTerminated, Reason = %d, peer = 0x%" PRIX64 "\n",
                aInParam.mSubscriptionTerminated.mReason,
                aInParam.mSubscriptionTerminated.mHandler->GetPeerNodeId());
        switch (gFinalStatus)
        {
        case kPublisherCancel:
        case kPublisherAbort:
            initiator->mExchangeMgr->MessageLayer->SystemLayer->CancelTimer(MonitorPublisherCurrentState, initiator);
            break;
        case kClientCancel:
        case kClientAbort:
            initiator->mExchangeMgr->MessageLayer->SystemLayer->CancelTimer(MonitorClientCurrentState, initiator);
            break;
        case kIdle:
        default:
            break;
        }

        if (gNumDataChangeBeforeCancellation != 0)
        {
            initiator->mExchangeMgr->MessageLayer->SystemLayer->CancelTimer(HandleDataFlipTimeout, initiator);
        }

        if (initiator->mEnableRetry == false)
        {
            WeaveLogDetail(DataManagement, "%s %d", __FUNCTION__, __LINE__);
            HandlePublisherRelease();
            if (gEvaluateSuccessIteration == true)
            {
                WeaveLogDetail(DataManagement, "Mutual: Good Iteration");
                gEvaluateSuccessIteration = false;
            }
            gMutualSubscriptionEstablished = false;
            initiator->onCompleteTest();
        }
        break;

    default:
        SubscriptionHandler::DefaultEventHandler(aEvent, aInParam, aOutParam);
        break;
    }

exit:
    WeaveLogFunctError(err);
}

void MockWdmSubscriptionInitiatorImpl::HandleClientComplete(void *aAppState)
{
    WEAVE_ERROR err;
    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(aAppState);

    WeaveLogDetail(DataManagement, "%s %d", __FUNCTION__, __LINE__);

    if (gIsMutualSubscription == true)
    {
        WeaveLogDetail(DataManagement, "%s %d", __FUNCTION__, __LINE__);
        gEvaluateSuccessIteration = true;
        initiator->mWillRetry = false;
    }

    if (NULL != initiator->mSubscriptionClient)
    {
        if (gFinalStatus == kClientCancel)
        {
            err = initiator->mSubscriptionClient->EndSubscription();
            if (err != WEAVE_NO_ERROR)
            {
                initiator->mSubscriptionClient->AbortSubscription();
            }
        }
        if (gFinalStatus == kClientAbort)
        {
            (void)initiator->mSubscriptionClient->AbortSubscription();
        }
    }

    gInitiatorState.mDataflipCount = 0;
}

void MockWdmSubscriptionInitiatorImpl::HandlePublisherComplete()
{
    WeaveLogDetail(DataManagement, "%s %d", __FUNCTION__, __LINE__);

    if (gIsMutualSubscription == true)
    {
        WeaveLogDetail(DataManagement, "%s %d", __FUNCTION__, __LINE__);
        gEvaluateSuccessIteration = true;
    }

    if (NULL != gSubscriptionHandler)
    {
        if (gFinalStatus == kPublisherCancel)
        {
            (void)gSubscriptionHandler->EndSubscription();

        }
        if (gFinalStatus == kPublisherAbort)
        {
            (void)gSubscriptionHandler->AbortSubscription();
        }
    }
}

void MockWdmSubscriptionInitiatorImpl::HandlePublisherRelease()
{
    gSubscriptionHandler = NULL;
}

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
void MockWdmSubscriptionInitiatorImpl::HandleMutationTimeout(nl::Weave::System::Layer* aSystemLayer, void *aAppState,
    nl::Weave::System::Error aErr)
{
    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(aAppState);

    if (initiator->mUpdateMutationCounter < initiator->mUpdateNumMutations)
    {
        initiator->ApplyWdmUpdateMutations();
    }
    else if (initiator->mUpdateTiming == MockWdmNodeOptions::kTiming_NoSub)
    {
        aSystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorClientCurrentState, initiator);
    }
}

WEAVE_ERROR MockWdmSubscriptionInitiatorImpl::ApplyWdmUpdateMutations()
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    int tmp;
    MockWdmSubscriptionInitiatorImpl *initiator = this;
    MockWdmNodeOptions::WdmUpdateConditionality conditionality = initiator->mUpdateConditionality;
    static bool testATraitConditional = true;
    static bool otherTraitsConditional = true;

    switch (conditionality)
    {
        case MockWdmNodeOptions::kConditionality_Conditional:
            testATraitConditional = true;
            otherTraitsConditional = true;
            break;
        case MockWdmNodeOptions::kConditionality_Unconditional:
            testATraitConditional = false;
            otherTraitsConditional = false;
            break;
        case MockWdmNodeOptions::kConditionality_Mixed:
            testATraitConditional = true;
            otherTraitsConditional = ! testATraitConditional;
            break;
        case MockWdmNodeOptions::kConditionality_Alternate:
            testATraitConditional = ! testATraitConditional;
            otherTraitsConditional = ! testATraitConditional;
            break;
        default:
            WeaveDie();
            break;
    }

    mUpdateMutationCounter++;

    WeaveLogDetail(DataManagement, "Mutation %u of %u; %u trait instances",
            initiator->mUpdateMutationCounter, initiator->mUpdateNumMutations, initiator->mUpdateNumTraits);
    switch (initiator->mUpdateNumTraits)
    {
        case 4:
            err = initiator->mTestATraitUpdatableDataSink1.Mutate(initiator->mSubscriptionClient, otherTraitsConditional, initiator->mUpdateMutation);
            SuccessOrExit(err);
        case 3:
            err = initiator->mTestBTraitUpdatableDataSink.Mutate(initiator->mSubscriptionClient, otherTraitsConditional, initiator->mUpdateMutation);
            SuccessOrExit(err);
        case 2:
            err = initiator->mLocaleSettingsTraitUpdatableDataSink.Mutate(initiator->mSubscriptionClient, otherTraitsConditional, initiator->mUpdateMutation);
            SuccessOrExit(err);
        case 1:
            err = initiator->mTestATraitUpdatableDataSink0.Mutate(initiator->mSubscriptionClient, testATraitConditional, initiator->mUpdateMutation);
            SuccessOrExit(err);
            break;
        default:
            err = initiator->mLocaleSettingsTraitUpdatableDataSink.Mutate(initiator->mSubscriptionClient, otherTraitsConditional, initiator->mUpdateMutation);
            SuccessOrExit(err);
            break;
    }
    err = initiator->mSubscriptionClient->FlushUpdate();

    initiator->mUpdateSameMutationCounter++;
    if (initiator->mUpdateSameMutationCounter == initiator->mUpdateNumRepeatedMutations)
    {
        initiator->mUpdateSameMutationCounter = 0;
        tmp = initiator->mUpdateMutation;
        tmp = (tmp + 1) % MockWdmNodeOptions::kMutation_NumItems;
        initiator->mUpdateMutation = static_cast<MockWdmNodeOptions::WdmUpdateMutation>(tmp);
    }

    SuccessOrExit(err);

    err = initiator->mExchangeMgr->MessageLayer->SystemLayer->StartTimer(5, HandleMutationTimeout, initiator);
    SuccessOrExit(err);

exit:
    return err;
}
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE

void MockWdmSubscriptionInitiatorImpl::HandleDataFlipTimeout(nl::Weave::System::Layer* aSystemLayer, void *aAppState,
    nl::Weave::System::Error aErr)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(aAppState);

    IgnoreUnusedVariable(aErr);

    if (gIsMutualSubscription == true && gMutualSubscriptionEstablished == false)
    {
        WeaveLogDetail(DataManagement, "mutual subscription cannot be established, and do nothing until response timeout happens");
        return;
    }

    if (gIsMutualSubscription == false && gOnewaySubscriptionEstablished == false)
    {
        WeaveLogDetail(DataManagement, "one way subscription cannot be established, and do nothing until response timeout happens");
        return;
    }

    ++gInitiatorState.mDataflipCount;

    if (gNumDataChangeBeforeCancellation != -1 && gInitiatorState.mDataflipCount > gNumDataChangeBeforeCancellation)
    {
        if (gIsMutualSubscription)
        {
            switch (gFinalStatus)
            {
                case kPublisherCancel:
                case kPublisherAbort:
                    aSystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorPublisherCurrentState, initiator);
                    break;
                case kClientCancel:
                case kClientAbort:
                    aSystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorClientCurrentState, initiator);
                    break;
            }
        }
        else
        {
            aSystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorClientCurrentState, initiator);
        }
        WeaveLogDetail(DataManagement, "No more data flips; started the MonitorClientCurrentState timer", gInitiatorState.mDataflipCount, gNumDataChangeBeforeCancellation);
        ExitNow();
    }
    else
    {
        // alter data every gTimeBetweenDataChangeMsec milliseconds
        WeaveLogDetail(DataManagement, "Cycle %d of %d", gInitiatorState.mDataflipCount, gNumDataChangeBeforeCancellation);
        WeaveLogDetail(DataManagement, "Starting timer for the next cycle");
        aSystemLayer->StartTimer(gTimeBetweenDataChangeMsec, HandleDataFlipTimeout, initiator);
    }

    if (gIsMutualSubscription == true && gEnableDataFlip == true) {
        WeaveLogDetail(DataManagement, "\n\n\n\n\nFlipping data...");

        switch (initiator->mTestCaseId)
        {
        case kTestCase_IntegrationTrait:
        case kTestCase_RejectIncomingSubscribeRequest:
            initiator->mLocaleCapabilitiesDataSource.Mutate();
            SubscriptionEngine::GetInstance()->GetNotificationEngine()->Run();
            break;
        case kTestCase_TestTrait:
            initiator->mTestATraitDataSource0.Mutate();
            initiator->mTestATraitDataSource1.Mutate();
            initiator->mTestBTraitDataSource.Mutate();
            SubscriptionEngine::GetInstance()->GetNotificationEngine()->Run();
            break;

#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
        case kTestCase_TestUpdatableTraits:
        {
            err = aSystemLayer->StartTimer(5, HandleMutationTimeout, initiator);
            SuccessOrExit(err);
            break;
        }
#endif // WEAVE_CONFIG_ENABLE_WDM_UPDATE

        case kTestCase_TestOversizeTrait1:
        case kTestCase_TestOversizeTrait2:
            initiator->mTestATraitDataSource0.Mutate();
            initiator->mTestATraitDataSource1.Mutate();
            SubscriptionEngine::GetInstance()->GetNotificationEngine()->Run();
            break;
        }
        initiator->DumpPublisherTraits();
    }

exit:
    WeaveLogFunctError(err);
}

void MockWdmSubscriptionInitiatorImpl::MonitorPublisherCurrentState (nl::Weave::System::Layer* aSystemLayer, void *aAppState, INET_ERROR aErr)
{
    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(aAppState);
    if (NULL != gSubscriptionHandler)
    {
        if (initiator->mSubscriptionClient->IsEstablishedIdle() && gSubscriptionHandler->IsEstablishedIdle())
        {
            WeaveLogDetail(DataManagement, "state transitions to idle within %d msec", kMonitorCurrentStateInterval * kMonitorCurrentStateCnt);
            gInitiatorState.mPublisherStateCount = 1;
            HandlePublisherComplete();
        }
        else
        {
            if (gInitiatorState.mPublisherStateCount < kMonitorCurrentStateCnt)
            {
                gInitiatorState.mPublisherStateCount ++;
                aSystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorPublisherCurrentState, initiator);
            }
            else
            {
                gInitiatorState.mPublisherStateCount = 1;
                WeaveLogDetail(DataManagement, "state is not idle or aborted within %d msec", kMonitorCurrentStateInterval * kMonitorCurrentStateCnt);
                (void)initiator->mSubscriptionClient->AbortSubscription();
                HandlePublisherRelease();
                initiator->onCompleteTest();
            }
        }
    }
    else
    {
        WeaveLogDetail(DataManagement, "gSubscriptionHandler is NULL, and current session is torn down");
        (void)initiator->mSubscriptionClient->AbortSubscription();
        HandlePublisherRelease();
        initiator->onCompleteTest();
    }

}

void MockWdmSubscriptionInitiatorImpl::MonitorClientCurrentState (nl::Weave::System::Layer* aSystemLayer, void *aAppState, INET_ERROR aErr)
{
    MockWdmSubscriptionInitiatorImpl * const initiator = reinterpret_cast<MockWdmSubscriptionInitiatorImpl *>(aAppState);
    if (NULL != initiator->mSubscriptionClient)
    {
        if (
#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
                (false == initiator->mSubscriptionClient->IsUpdatePendingOrInProgress() && initiator->mUpdateTiming == MockWdmNodeOptions::kTiming_NoSub) ||
#endif
                (initiator->mSubscriptionClient->IsEstablishedIdle() && (gIsMutualSubscription == false || gSubscriptionHandler->IsEstablishedIdle())))
        {
            WeaveLogDetail(DataManagement, "state transitions to idle within %d msec", kMonitorCurrentStateInterval * kMonitorCurrentStateCnt);
            gInitiatorState.mClientStateCount = 1;
            HandleClientComplete(initiator);

            if (gIsMutualSubscription == false)
            {
                WeaveLogDetail(DataManagement, "One_way: Good Iteration");
                initiator->onCompleteTest();
            }
        }
        else
        {
            if (gInitiatorState.mClientStateCount < kMonitorCurrentStateCnt)
            {
                WeaveLogDetail(DataManagement, "state is not idle or aborted yet; count: %d", gInitiatorState.mClientStateCount);
                gInitiatorState.mClientStateCount++;
                aSystemLayer->StartTimer(kMonitorCurrentStateInterval, MonitorClientCurrentState, initiator);
            }
            else
            {
                gInitiatorState.mClientStateCount = 1;
                WeaveLogDetail(DataManagement, "state is not idle or aborted within %d msec", kMonitorCurrentStateInterval * kMonitorCurrentStateCnt);
                (void)initiator->mSubscriptionClient->AbortSubscription();
                HandlePublisherRelease();
                initiator->onCompleteTest();

            }
        }
    }
    else
    {
        WeaveLogDetail(DataManagement, "mSubscriptionClient is NULL, and current session is torn down");
        HandlePublisherRelease();
        initiator->onCompleteTest();
    }
}
} // WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)
}
}
}

static nl::Weave::Profiles::DataManagement::MockWdmSubscriptionInitiatorImpl gWdmSubscriptionInitiator;
MockWdmSubscriptionInitiator * MockWdmSubscriptionInitiator::GetInstance(void)
{
    return &gWdmSubscriptionInitiator;
}

uint32_t MockWdmSubscriptionInitiator::GetNumUpdatableTraits(void)
{
#if WEAVE_CONFIG_ENABLE_WDM_UPDATE
    return 4;
#else
    return 0;
#endif
}


#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
