/*
 *
 *    Copyright (c) 2014-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 an application that is intended to be a
 *      comprehensive tester for all aspects of Weave Data Management
 *      (WDM) that one can test in standalone mode. As such, it tests
 *      data structures, subsystems and networked behaviors. The
 *      latter requires a mock device acting as a WDM server and using
 *      the same test profile.
 *
 */

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

#include <assert.h>

// This code tests the legacy version of Weave Data Management
#define WEAVE_CONFIG_DATA_MANAGEMENT_NAMESPACE kWeaveManagedNamespace_Legacy

#include "ToolCommon.h"
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Profiles/data-management/DataManagement.h>
#include <Weave/Profiles/data-management/ProfileDatabase.h>
#include "TestProfile.h"

using namespace ::nl::Inet;
using namespace ::nl::Weave;
using namespace ::nl::Weave::TLV;
using namespace ::nl::Weave::Profiles;
using namespace ::nl::Weave::Profiles::Common;
using namespace ::nl::Weave::Profiles::DataManagement;
using namespace ::nl::Weave::Profiles::StatusReporting;

#define TOOL_NAME "TestDataManagement"

static bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg);
static bool HandleNonOptionArgs(const char *progName, int argc, char *argv[]);
static void HandleConnectionReceived(WeaveMessageLayer *msgLayer, WeaveConnection *con);
static void HandleSecureSessionEstablished(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, uint16_t sessionKeyId, uint64_t peerNodeId, uint8_t encType);
static void HandleSecureSessionError(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, WEAVE_ERROR localErr, uint64_t peerNodeId, StatusReport *statusReport);
static void HandleConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr);
// static void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);

uint64_t DestNodeId;
IPAddress DestAddr = IPAddress::Any; // TODO BUG: This isn't used anywhere, despite being settable from the command-line.
bool Debug = false;

/*
 * in some circumstances we may want to use multiple clients and then
 * we have to count them to know when we're done.
 */

uint8_t gClientCount = 1;
uint8_t gClientCounter = 0;
int gCyclingCnt = 32;

static OptionDef gToolOptionDefs[] =
{
    { "dest-addr",      kArgumentRequired,  'D' },
    { "cycling-cnt",    kArgumentRequired,  'c' },
#if WEAVE_CONFIG_SECURITY_TEST_MODE
    { "allow-dups",     kNoArgument,        'A' },
#endif
    { }
};

static const char *gToolOptionHelp =
    "  -D, --dest-addr <dest-node-ip-addr>\n"
    "       Send weave messages to a specific IPv4/IPv6 address rather than one\n"
    "       derived the destination node id.\n"
    "\n"
    "  -c, --cycling-cnt <num>"
    "       The count of the cycling test\n"
    "\n"
#if WEAVE_CONFIG_SECURITY_TEST_MODE
    "  -A, --allow-dups\n"
    "       Allow reception of duplicate messages.\n"
    "\n"
#endif
    "";

static OptionSet gToolOptions =
{
    HandleOption,
    gToolOptionDefs,
    "GENERAL OPTIONS",
    gToolOptionHelp
};

static HelpOptions gHelpOptions(
    TOOL_NAME,
    "Usage: " TOOL_NAME " [<options...>] [<dest-node-id>]\n",
    WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT
);

static OptionSet *gToolOptionSets[] =
{
    &gToolOptions,
    &gNetworkOptions,
    &gWeaveNodeOptions,
    &gFaultInjectionOptions,
    &gHelpOptions,
    NULL
};

#define EnterTest(_name_, _errName_)                 \
  WEAVE_ERROR _errName_ = (                          \
    printf("\n\n"                                    \
           _name_                                    \
           "---\n"),                                 \
    WEAVE_NO_ERROR                                   \
  )

#define DriveTest(_done_)                            \
  do {                                               \
    while (!(_done_))                                \
    {                                                \
        struct timeval sleepTime;                    \
        sleepTime.tv_sec = 0;                        \
        sleepTime.tv_usec = 100000;                  \
        ServiceNetwork(sleepTime);                   \
    }                                                \
  } while (0)

#define ExitTest(_err_)                              \
  do {                                               \
    if ((_err_) == WEAVE_NO_ERROR)                   \
        printf("Success\n");                         \
    else                                             \
    {                                                \
        printf("error: %s\n", ErrorStr(_err_));      \
        exit(-1);                                    \
    }                                                \
  } while (0)

static WEAVE_ERROR ValidatePath(TLVReader &aReader,
                                const uint64_t &aTag,
                                uint32_t aProfileId,
                                const uint64_t &aInstanceId,
                                uint32_t aPathLen,
                                ...)
{
    WEAVE_ERROR err;

    va_list pathTags;

    TLVType pathContainer;
    TLVType profileContainer;

    uint32_t profileId;
    uint64_t instanceId = kInstanceIdNotSpecified;

    // This following line must be executed before the execution flow could possibly reach the exit label,
    // for we call va_end at there unconditionally.
    va_start(pathTags, aPathLen);

    VerifyOrExit((aReader.GetType() == kTLVType_Path), err = WEAVE_ERROR_WRONG_TLV_TYPE);

    err = ValidateWDMTag(aTag, aReader);
    SuccessOrExit(err);

    err = aReader.EnterContainer(pathContainer);
    SuccessOrExit(err);

    /*
     * the first element of a path under WDM should be a structure
     * with 2 elements, one of which (the instance) is optional.
     */

    err = aReader.Next();
    SuccessOrExit(err);

    VerifyOrExit(aReader.GetType() == kTLVType_Structure, err = WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT);

    err = ValidateWDMTag(kTag_WDMPathProfile, aReader);
    SuccessOrExit(err);

    /*
     * check the path profile and instance
     */

    err = aReader.EnterContainer(profileContainer);
    SuccessOrExit(err);

    /*
     * the first element here should be a profile ID
     */

    err = aReader.Next();
    SuccessOrExit(err);

    err = ValidateWDMTag(kTag_WDMPathProfileId, aReader);
    SuccessOrExit(err);

    err = aReader.Get(profileId);
    SuccessOrExit(err);

    VerifyOrExit(profileId == aProfileId, err = WEAVE_ERROR_INVALID_PROFILE_ID);

    /*
     * and the second may be an instance
     */

    err = aReader.Next();

    if (err != WEAVE_END_OF_TLV)
    {
        err = ValidateWDMTag(kTag_WDMPathProfileInstance, aReader);
        SuccessOrExit(err);

        err = aReader.Get(instanceId);
        SuccessOrExit(err);
    }

    VerifyOrExit(instanceId == aInstanceId, err = WEAVE_ERROR_INCORRECT_STATE);

    err = aReader.ExitContainer(profileContainer);
    SuccessOrExit(err);

    // now, the residual path elements, if any

    for (uint32_t i = 0; i < aPathLen; i++)
    {
        err = aReader.Next();
        SuccessOrExit(err);

        if (err == WEAVE_NO_ERROR)
        {
            if (aReader.GetTag() != va_arg(pathTags, uint64_t))
            {
                err = WEAVE_ERROR_INVALID_TLV_TAG;

                break;
            }
        }

        else
        {
            err = WEAVE_ERROR_TLV_UNDERRUN;
            break;
        }
    }

    /*
     * again, don't hide the error that caused us to exit behind
     * the error you might get trying to exit the conmtainer.
     */

    if (err == WEAVE_NO_ERROR)
        err = aReader.ExitContainer(pathContainer);

    else
        aReader.ExitContainer(pathContainer);

exit:
    va_end(pathTags);

    return err;
}

/*
 * in order to use the "new improved" data management, we have to create
 * a sub-class of the WDM client and supply the relevant methods as follows.
 */

class DMTestClient :
    public DMClient
{
public:
    WEAVE_ERROR ViewConfirm(const uint64_t &aResponderId, StatusReport &aStatus, uint16_t aTxnId)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        printf("processing: <view confirm - non-success status>\n");

        Done = true;

        return err;
    }

    WEAVE_ERROR ViewConfirm(const uint64_t &aResponderId, ReferencedTLVData &aDataList, uint16_t aTxnId)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        printf("processing: <view confirm - success status>\n");

        err = mDatabase.Store(aDataList);

        if (err != WEAVE_NO_ERROR)
            printf("<view confirm> error: %x\n", err);

        Done = true;

        return err;
    }

    WEAVE_ERROR UpdateConfirm(const uint64_t &aResponderId, StatusReport &aStatus, uint16_t aTxnId)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        if (aStatus.success())
            printf("processing: <update confirm - success!>\n");

        else
            printf("processing: <update confirm - non-success status>\n");

        Done = true;

        return err;
    }

    void IncompleteIndication(const uint64_t &aPeerNodeId, StatusReport &aReport)
    {
        printf("processing: <incomplete indication>\n");
    }

#if WEAVE_CONFIG_WDM_ALLOW_CLIENT_SUBSCRIPTION

    WEAVE_ERROR SubscribeConfirm(const uint64_t &aResponderId, StatusReport &aStatus, uint16_t aTxnId)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        printf("processing: <subscribe confirm - non-success status>\n");

        gClientCounter++;

        if (gClientCounter == gClientCount)
            Done = true;

        return err;
    }

    WEAVE_ERROR SubscribeConfirm(const uint64_t &aResponderId,
                                 const TopicIdentifier &aTopicId,
                                 uint16_t aTxnId)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        printf("processing: <subscribe confirm - success status, no data list>\n");

        Done = true;

        return err;
    }

    WEAVE_ERROR SubscribeConfirm(const uint64_t &aResponderId,
                                 const TopicIdentifier &aTopicId,
                                 ReferencedTLVData &aDataList,
                                 uint16_t aTxnId)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        printf("processing: <subscribe confirm - success status + data list>\n");

        // and install the data

        err = mDatabase.Store(aDataList);
        SuccessOrExit(err);

        gClientCounter++;

        if (gClientCounter == gClientCount)
            Done = true;

    exit:
        if (err != WEAVE_NO_ERROR)
            printf("<subscribe confirm> error: %s\n", ErrorStr(err));

        return err;
    }

    WEAVE_ERROR UnsubscribeIndication(const uint64_t &aPublisherId, const TopicIdentifier &aTopicId, StatusReport &aReport)
    {
    printf("processing: <unsubscribe indication 0x%" PRIx64 ", 0x%" PRIx64 ">\n", aPublisherId, aTopicId);

    return WEAVE_NO_ERROR;
    }

    WEAVE_ERROR CancelSubscriptionConfirm(const uint64_t &aResponderId, const TopicIdentifier &aTopicId, StatusReport &aStatus, uint16_t aTxnId)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        printf("processing: <cancel subscription confirm>\n");

        if (aStatus.success())
            printf("status == success\n");

        else
            printf("non-success status: <%x, %x>\n", aStatus.mProfileId, aStatus.mStatusCode);

        gClientCounter++;

        if (gClientCounter == gClientCount)
            Done = true;

        return err;
    }

    WEAVE_ERROR NotifyIndication(const TopicIdentifier &aTopicId, ReferencedTLVData &aDataList)
    {
        WEAVE_ERROR err = WEAVE_NO_ERROR;

        printf("processing: <notify indication>\n");

        err = mDatabase.Store(aDataList);

        gClientCounter++;

        if (gClientCounter == gClientCount)
            Done = true;

        return err;
    }

#endif // WEAVE_CONFIG_WDM_ALLOW_CLIENT_SUBSCRIPTION

    /*
     * the client comes with a profile database
     */

    TestProfileDB mDatabase;
};

/*
 * and we need a test rig, which is basically a place to hang tests, all
 * of which are run from the client side.
 */

class DMClientTester
{
public:
    DMClientTester(uint8_t aTransport)
    {
        mTransport = aTransport;
    }

    /*
     * test cases
     */

    void Test_InitialState()
    {
        DMTestClient client;

        EnterTest("InitialState", err);

        assert(client.mDatabase.mTestData.mVersion == 0);
        assert(client.mDatabase.mTestData.mIntegerItem == 0);

        ExitTest(err);
    }

    void Test_DBStore()
    {
        DMTestClient client;

        EnterTest("DBStore", err);

        uint8_t buf[kTestBufferSize];
        TLVWriter writer;
        ReferencedTLVData dataList;

        // write a data list to store (including new version)

        writer.Init(buf, kTestBufferSize);

        err = StartDataList(writer);
        SuccessOrExit(err);

        err = StartDataListElement(writer);
        SuccessOrExit(err);

        err = EncodePath(writer,
                         ContextTag(kTag_WDMDataListElementPath),
                         kWeaveProfile_Test,
                         kInstanceIdNotSpecified,
                         1,
                         ContextTag(kTag_IntegerItem));
        SuccessOrExit(err);

        err = writer.Put(ContextTag(kTag_WDMDataListElementVersion), (uint64_t)1); // increment version
        SuccessOrExit(err);

        err = writer.Put(ContextTag(kTag_WDMDataListElementData), 1); // write 1
        SuccessOrExit(err);

        err = EndDataListElement(writer);
        SuccessOrExit(err);

        err = EndList(writer);
        SuccessOrExit(err);

        // now store it and confirm results

        err = dataList.init(writer.GetLengthWritten(), kTestBufferSize, buf);
        SuccessOrExit(err);

        err = client.mDatabase.Store(dataList);
        SuccessOrExit(err);

        assert(client.mDatabase.mTestData.mVersion == 1); // check for 1
        assert(client.mDatabase.mTestData.mIntegerItem == 1); // check for 1

    exit:
        ExitTest(err);
    }

    void Test_DBRetrieve()
    {
        DMTestClient client;

        EnterTest("DBRetrieve", err);

        uint8_t pathBuf[kTestBufferSize];
        TLVWriter writer;
        ReferencedTLVData pathList;

        uint8_t dataBuf[kTestBufferSize];
        ReferencedTLVData dataList;

        TLVReader dataListRdr;
        TLVReader pathRdr;
        uint64_t version;

        uint32_t item;

        // write a path list to extract a data item

        writer.Init(pathBuf, kTestBufferSize);

        err = StartPathList(writer);
        SuccessOrExit(err);

        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Test, kInstanceIdNotSpecified, 1, ContextTag(kTag_IntegerItem));
        SuccessOrExit(err);

        err = EndList(writer);
        SuccessOrExit(err);

        err = writer.Finalize();
        SuccessOrExit(err);

        err = pathList.init(writer.GetLengthWritten(), kTestBufferSize, pathBuf);
        SuccessOrExit(err);

        // set up the data list to receive data

        err = dataList.init(0, kTestBufferSize, dataBuf);
        SuccessOrExit(err);

        // now do the retrieve

        err = client.mDatabase.Retrieve(pathList, dataList);
        SuccessOrExit(err);

        // validate the data list

        OpenDataList(dataList, dataListRdr);
        SuccessOrExit(err);

        err = dataListRdr.Next();
        SuccessOrExit(err);

        err = OpenDataListElement(dataListRdr, pathRdr, version);
        SuccessOrExit(err);

        err = ValidatePath(pathRdr,
                           ContextTag(kTag_WDMDataListElementPath),
                           kWeaveProfile_Test,
                           kInstanceIdNotSpecified,
                           1,
                           ContextTag(kTag_IntegerItem));
        SuccessOrExit(err);

        assert(version == client.mDatabase.mTestData.mVersion); // check version

        assert(CheckWDMTag(kTag_WDMDataListElementData, dataListRdr)); // check data tag

        assert(dataListRdr.GetType() == kTLVType_UnsignedInteger); // check data type

        err = dataListRdr.Get(item);
        SuccessOrExit(err);
        assert(item == client.mDatabase.mTestData.mIntegerItem); // check data

        err = CloseDataListElement(dataListRdr);
        SuccessOrExit(err);

        err = CloseList(dataListRdr);
        SuccessOrExit(err);

    exit:
        ExitTest(err);
    }

    void Test_DBRetrieveAndStore()
    {
        DMTestClient client;

        EnterTest("DBRetrieveAndStore", err);

        uint8_t pathBuf[kTestBufferSize];
        TLVWriter writer;
        ReferencedTLVData pathList;

        uint8_t dataBuf[kTestBufferSize];
        ReferencedTLVData dataList;

        // check inital state

        assert(client.mDatabase.mTestData.mVersion == 0);
        assert(client.mDatabase.mTestData.mIntegerItem == 0);

        // write a path list to extract the whole bucket

        writer.Init(pathBuf, kTestBufferSize);

        err = StartPathList(writer);
        SuccessOrExit(err);

        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Test, kInstanceIdNotSpecified, 0);
        SuccessOrExit(err);

        err = EndList(writer);
        SuccessOrExit(err);

        err = writer.Finalize();
        SuccessOrExit(err);

        err = pathList.init(writer.GetLengthWritten(), kTestBufferSize, pathBuf);
        SuccessOrExit(err);

        // set up the data list to receive data

        err = dataList.init(0, kTestBufferSize, dataBuf);
        SuccessOrExit(err);

        // now do the retrieve

        err = client.mDatabase.Retrieve(pathList, dataList);
        SuccessOrExit(err);

        /*
         * OK, so here's what we do now. we've got a data list capturing the
         * original state. change the state and then verify that we can set it
         * back by applying the data list.
         */

        client.mDatabase.mTestData.mVersion = 1;
        client.mDatabase.mTestData.mIntegerItem = 1;

        err = client.mDatabase.Store(dataList);
        SuccessOrExit(err);

        assert(client.mDatabase.mTestData.mVersion == 0);
        assert(client.mDatabase.mTestData.mIntegerItem == 0);

    exit:
        ExitTest(err);
    }

    void Test_View(void)
    {
        DMTestClient client;

        uint8_t pathBuf[kTestBufferSize];

        TLVWriter writer;
        ReferencedTLVData pathList;

        EnterTest("DBView", err);

        // set up the client

        err = client.Init(&ExchangeMgr);
        SuccessOrExit(err);

        err = client.BindRequest(DestNodeId, mTransport);
        SuccessOrExit(err);

        // now, make a path list

        writer.Init(pathBuf, kTestBufferSize);

        err = StartPathList(writer);
        SuccessOrExit(err);

        // first path
        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Test, kInstanceIdNotSpecified, 0);
        SuccessOrExit(err);

        // second path
        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Test, kInstanceIdNotSpecified, 0);
        SuccessOrExit(err);

        err = EndList(writer);
        SuccessOrExit(err);

        err = writer.Finalize();
        SuccessOrExit(err);

        err = pathList.init(writer.GetLengthWritten(), kTestBufferSize, pathBuf);
        SuccessOrExit(err);

        /*
         * do this a bunch of times to test resource management
         */

        for (int i = 0; i < gCyclingCnt; i++)
        {
            err = client.ViewRequest(pathList, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // now drive
            Done = false;
            DriveTest(Done);
        }

        err = client.ViewRequest(DestNodeId, pathList, 1, kDefaultDMResponseTimeout);
        SuccessOrExit(err);

        // now drive
        Done = false;
        DriveTest(Done);

    exit:
        ExitTest(err);
    }

    void Test_Update(void)
    {
        DMTestClient client;

        uint8_t pathBuf[kTestBufferSize];
        TLVWriter writer;
        ReferencedTLVData pathList;

        uint8_t dataBuf[kTestBufferSize];
        ReferencedTLVData dataList;

        EnterTest("DBUpdate", err);

        // set up the client

        err = client.Init(&ExchangeMgr);
        SuccessOrExit(err);

        err = client.BindRequest(DestNodeId, mTransport);
        SuccessOrExit(err);

        // now, make a path list

        writer.Init(pathBuf, kTestBufferSize);

        err = StartPathList(writer);
        SuccessOrExit(err);

        // first path
        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Test, kInstanceIdNotSpecified, 1, ContextTag(kTag_IntegerItem));
        SuccessOrExit(err);

        // second path
        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Test, kInstanceIdNotSpecified, 1, ContextTag(kTag_IntegerItem));
        SuccessOrExit(err);

        err = EndList(writer);
        SuccessOrExit(err);

        err = writer.Finalize();
        SuccessOrExit(err);

        err = pathList.init(writer.GetLengthWritten(), kTestBufferSize, pathBuf);
        SuccessOrExit(err);

        for (uint16_t i = 0; i < gCyclingCnt; i++)
        {
            uint64_t currentVersion = client.mDatabase.mTestData.mVersion;
            client.mDatabase.mTestData.mIntegerItem = i;

            // use path list to extract a data list

            err = dataList.init(0, kTestBufferSize, dataBuf);
            SuccessOrExit(err);

            err = client.mDatabase.Retrieve(pathList, dataList);
            SuccessOrExit(err);

            // send an update

#if WEAVE_CONFIG_WDM_ALLOW_CLIENT_LEGACY_MESSAGE_TYPES

            // it we're allowing old message types, send some

            if (i % 3 == 0)
            {
                err = client.UpdateRequest(dataList, 1, kDefaultDMResponseTimeout, true);
                SuccessOrExit(err);
            }
            else if (i % 3 == 1)
            {
                err = client.UpdateRequest(dataList, 1, kDefaultDMResponseTimeout);
                SuccessOrExit(err);
            }
            else if (i % 3 == 2)
            {
                err = client.UpdateRequest(DestNodeId, dataList, 1, kDefaultDMResponseTimeout);
                SuccessOrExit(err);
            }

#else

            err = client.UpdateRequest(dataList, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

#endif // WEAVE_CONFIG_WDM_ALLOW_CLIENT_LEGACY_MESSAGE_TYPES

            // now drive

            Done = false;
            DriveTest(Done);

            // OK, now send a view

            err = client.ViewRequest(pathList, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // and again...

            Done = false;
            DriveTest(Done);

            // now check the results

            assert(client.mDatabase.mTestData.mIntegerItem == i);
            assert(client.mDatabase.mTestData.mVersion > currentVersion);
        }

    exit:
        ExitTest(err);
    }

#if WEAVE_CONFIG_WDM_ALLOW_CLIENT_SUBSCRIPTION

    void Test_CancelNonSubscription(void)
    {
        DMTestClient client;

        gClientCount = 1;

        EnterTest("CancelNonSubscription", err);

        // set up the client with subscription enabled

        err = client.Init(&ExchangeMgr);
        SuccessOrExit(err);

        err = client.BindRequest(DestNodeId, mTransport);
        SuccessOrExit(err);

        for (uint16_t i = 0; i < gCyclingCnt; i++)
        {
            /*
             * insert the subscription so there'll be something there.
             */

            err = DMClient::sNotifier.InstallSubscription(kTopicIdNotSpecified, kTestTopic, DestNodeId, &client);
            SuccessOrExit(err);

            // now cancel

            err = client.CancelSubscriptionRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // drive

            Done = false;
            gClientCounter = 0;
            DriveTest(Done);

            assert(!client.HasSubscription(kTestTopic));
        }

    exit:
        ExitTest(err);
    }

    void Test_SubscribeToTopic(void)
    {
        DMTestClient client;

        uint8_t pathBuf[kTestBufferSize];
        TLVWriter writer;
        ReferencedTLVData pathList;

        gClientCount = 1;

        EnterTest("SubscribeToTopic", err);

        // set up the client with subscription enabled

        err = client.Init(&ExchangeMgr);
        SuccessOrExit(err);

        err = client.BindRequest(DestNodeId, mTransport);
        SuccessOrExit(err);

        writer.Init(pathBuf, kTestBufferSize);

        err = StartPathList(writer);
        SuccessOrExit(err);

        // first path
        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Test, kInstanceIdNotSpecified, 1, ContextTag(kTag_IntegerItem));
        SuccessOrExit(err);

        err = EndList(writer);
        SuccessOrExit(err);

        err = writer.Finalize();
        SuccessOrExit(err);

        err = pathList.init(writer.GetLengthWritten(), kTestBufferSize, pathBuf);
        SuccessOrExit(err);

        err = client.SubscribeRequest(DestNodeId, pathList, 1, kDefaultDMResponseTimeout);
        SuccessOrExit(err);

        err = client.CancelSubscriptionRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
        SuccessOrExit(err);

        Done = false;
        gClientCounter = 0;
        DriveTest(Done);

        assert(!client.HasSubscription(kTestTopic));

        err = client.SubscribeRequest(pathList, 1, kDefaultDMResponseTimeout);
        SuccessOrExit(err);

        err = client.CancelSubscriptionRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
        SuccessOrExit(err);

        Done = false;
        gClientCounter = 0;
        DriveTest(Done);

        assert(!client.HasSubscription(kTestTopic));

        err = client.SubscribeRequest(DestNodeId, kTestTopic, 1, kDefaultDMResponseTimeout);
        SuccessOrExit(err);

        Done = false;
        gClientCounter = 0;
        DriveTest(Done);

        assert(client.HasSubscription(kTestTopic));

        err = client.CancelSubscriptionRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
        SuccessOrExit(err);

        Done = false;
        gClientCounter = 0;
        DriveTest(Done);

        assert(!client.HasSubscription(kTestTopic));

        err = client.CancelTransactionRequest(1, err);
        SuccessOrExit(err);


        for (uint16_t i = 0; i < gCyclingCnt; i++)
        {
            err = client.SubscribeRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // now drive

            Done = false;
            gClientCounter = 0;
            DriveTest(Done);

            assert(client.HasSubscription(kTestTopic));

            // now wait for a notification

            Done = false;
            gClientCounter = 0;
            DriveTest(Done);

            // now cancel

            err = client.CancelSubscriptionRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // drive s'more

            Done = false;
            gClientCounter = 0;
            DriveTest(Done);

            assert(!client.HasSubscription(kTestTopic));

        }

    exit:
        ExitTest(err);
    }

    void Test_MultipleClients(void)
    {
        DMTestClient client1;
        DMTestClient client2;

        gClientCount = 2;

        EnterTest("MultipleClients", err);

        // set up the client with subscription enabled

        err = client1.Init(&ExchangeMgr);
        SuccessOrExit(err);

        err = client2.Init(&ExchangeMgr);
        SuccessOrExit(err);

        err = client1.BindRequest(DestNodeId, mTransport);
        SuccessOrExit(err);
        err = client2.BindRequest(DestNodeId, mTransport);
        SuccessOrExit(err);

        for (uint16_t i = 0; i < gCyclingCnt; i++)
        {
            err = client1.SubscribeRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            Done = false;
            gClientCounter = 0;
            DriveTest(Done);

            err = client2.SubscribeRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // now drive

            Done = false;
            gClientCounter = 0;
            DriveTest(Done);

            assert(client1.HasSubscription(kTestTopic));
            assert(client2.HasSubscription(kTestTopic));

            // now wait for a notification

            Done = false;
            gClientCounter = 0;
            DriveTest(Done);

            // now cancel

            err = client1.CancelSubscriptionRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            err = client2.CancelSubscriptionRequest(kTestTopic, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // drive s'more

            Done = false;
            gClientCounter = 0;
            DriveTest(Done);

            assert(!client1.HasSubscription(kTestTopic));
            assert(!client2.HasSubscription(kTestTopic));
        }

    exit:
        ExitTest(err);
    }

#endif // WEAVE_CONFIG_WDM_ALLOW_CLIENT_SUBSCRIPTION

    void Test_CloseConnection(void)
    {
        DMTestClient client;

        uint8_t pathBuf[kTestBufferSize];
        TLVWriter writer;
        ReferencedTLVData pathList;

        EnterTest("CloseConnection", err);

        // set up the client

        err = client.Init(&ExchangeMgr);
        SuccessOrExit(err);

        err = client.BindRequest(DestNodeId, kTransport_TCP);
        SuccessOrExit(err);

        // now, make a "special" path list

        writer.Init(pathBuf, kTestBufferSize);

        err = StartPathList(writer);
        SuccessOrExit(err);

        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Fail, kFailureInstance_CloseConnection, 0);
        SuccessOrExit(err);

        err = EndList(writer);
        SuccessOrExit(err);

        err = writer.Finalize();
        SuccessOrExit(err);

        err = pathList.init(writer.GetLengthWritten(), kTestBufferSize, pathBuf);
        SuccessOrExit(err);

        /*
         * do this a bunch of times to test resource management
         */

        for (int i = 0; i < gCyclingCnt; i++)
        {
            err = client.ViewRequest(pathList, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // now drive
            Done = false;
            DriveTest(Done);
        }

    exit:
        ExitTest(err);
    }

    void Test_NoResponse(void)
    {
        DMTestClient client;

        uint8_t pathBuf[kTestBufferSize];
        TLVWriter writer;
        ReferencedTLVData pathList;

        EnterTest("NoResponse", err);

        // set up the client

        err = client.Init(&ExchangeMgr);
        SuccessOrExit(err);

        err = client.BindRequest(DestNodeId, mTransport);
        SuccessOrExit(err);

        // now, make a "special" path list

        writer.Init(pathBuf, kTestBufferSize);

        err = StartPathList(writer);
        SuccessOrExit(err);

        err = EncodePath(writer, AnonymousTag, kWeaveProfile_Fail, kFailureInstance_NoResponse, 0);
        SuccessOrExit(err);

        err = EndList(writer);
        SuccessOrExit(err);

        err = writer.Finalize();
        SuccessOrExit(err);

        err = pathList.init(writer.GetLengthWritten(), kTestBufferSize, pathBuf);
        SuccessOrExit(err);

        /*
         * do this a bunch of times to test resource management
         */

        for (int i = 0; i < gCyclingCnt; i++)
        {
            err = client.ViewRequest(pathList, 1, kDefaultDMResponseTimeout);
            SuccessOrExit(err);

            // now drive
            Done = false;
            DriveTest(Done);
        }

    exit:
        ExitTest(err);
    }

    static void Run(void)
    {
        printf("Running WDM client tests---\n");

        /*
         * check the profile database operaiton
         */

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_InitialState();
        }

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_DBStore();
        }

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_DBRetrieve();
        }

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_DBRetrieveAndStore();
        }

        /*
         * then the client notifier stuff
         */

        /*
         * and the server subscription table
         */

        /*
         * OK, now test the stuff that actually requires communication
         */

        // test view

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_View();
        }
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
        {
            DMClientTester tester(kTransport_WRMP);

            tester.Test_View();
        }
#endif
        // and using TCP

        {
            DMClientTester tester(kTransport_TCP);

            tester.Test_View();
        }

        // test update

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_Update();
        }
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
        {
            DMClientTester tester(kTransport_WRMP);

            tester.Test_Update();
        }
#endif
        {
            DMClientTester tester(kTransport_TCP);

            tester.Test_Update();
        }

#if WEAVE_CONFIG_WDM_ALLOW_CLIENT_SUBSCRIPTION

        // cancel a non-existent subscription

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_CancelNonSubscription();
        }
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
        {
            DMClientTester tester(kTransport_WRMP);

            tester.Test_CancelNonSubscription();
        }
#endif
        {
            DMClientTester tester(kTransport_TCP);

            tester.Test_CancelNonSubscription();
        }

        // now try establishing a topic subscription

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_SubscribeToTopic();
        }

#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
        {
            DMClientTester tester(kTransport_WRMP);

            tester.Test_SubscribeToTopic();
        }
#endif
        {
            DMClientTester tester(kTransport_TCP);

            tester.Test_SubscribeToTopic();
        }

        // do the same with multiple clients

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_MultipleClients();
        }
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
        {
            DMClientTester tester(kTransport_WRMP);

            tester.Test_MultipleClients();
        }
#endif
        {
            DMClientTester tester(kTransport_TCP);

            tester.Test_MultipleClients();
        }

#endif // WEAVE_CONFIG_WDM_ALLOW_CLIENT_SUBSCRIPTION

        // these are negative tests

        {
            DMClientTester tester(kTransport_TCP);

            tester.Test_CloseConnection();
        }

        {
            DMClientTester tester(kTransport_UDP);

            tester.Test_NoResponse();
        }

        {
            DMClientTester tester(kTransport_TCP);

            tester.Test_NoResponse();
        }
#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING
        {
            DMClientTester tester(kTransport_WRMP);

            tester.Test_NoResponse();
        }
#endif
    }

    // we need to keep the transport around since the DME one is protected

    uint8_t mTransport;
};

int main(int argc, char *argv[])
{
    if (argc == 1)
    {
        gHelpOptions.PrintBriefUsage(stderr);
        exit(EXIT_FAILURE);
    }

    if (!ParseArgsFromEnvVar(TOOL_NAME, TOOL_OPTIONS_ENV_VAR_NAME, gToolOptionSets, NULL, true) ||
        !ParseArgs(TOOL_NAME, argc, argv, gToolOptionSets, HandleNonOptionArgs) ||
        !ResolveWeaveNetworkOptions(TOOL_NAME, gWeaveNodeOptions, gNetworkOptions))
    {
        exit(EXIT_FAILURE);
    }

    InitSystemLayer();

    InitNetwork();

    InitWeaveStack(false, true);

    // Arrange to get called for various activity in the message layer.
    MessageLayer.OnConnectionReceived = HandleConnectionReceived;
    MessageLayer.OnReceiveError = HandleMessageReceiveError;
    MessageLayer.OnAcceptError = HandleAcceptConnectionError;

    SecurityMgr.OnSessionEstablished = HandleSecureSessionEstablished;
    SecurityMgr.OnSessionError = HandleSecureSessionError;

    if (DestAddr == IPAddress::Any)
        DestAddr = FabricState.SelectNodeAddress(DestNodeId);

    PrintNodeConfig();

    DMClientTester::Run();

    printf("WDM Test is Completed!\n");

    ShutdownWeaveStack();
    ShutdownNetwork();
    ShutdownSystemLayer();

    return EXIT_SUCCESS;
}

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 'D':
        if (!ParseIPAddress(arg, DestAddr))
        {
            PrintArgError("%s: Invalid value specified for destination IP address: %s\n", progName, arg);
            return false;
        }
        break;
    case 'c':
        if (!ParseInt(arg, gCyclingCnt))
        {
            PrintArgError("%s: Invalid value specified for cycling count: %s\n", progName, arg);
            return false;
        }
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

bool HandleNonOptionArgs(const char *progName, int argc, char *argv[])
{
    if (argc > 0)
    {
        if (argc > 1)
        {
            PrintArgError("%s: Unexpected argument: %s\n", progName, argv[1]);
            return false;
        }

        if (!ParseNodeId(argv[0], DestNodeId))
        {
            PrintArgError("%s: Invalid value specified for destination node-id: %s\n", progName, argv[0]);
            return false;
        }
    }

    return true;
}

void HandleConnectionReceived(WeaveMessageLayer *msgLayer, WeaveConnection *con)
{
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    printf("Connection received from node 0x%" PRIx64 " (%s)\n", con->PeerNodeId, ipAddrStr);

    con->OnConnectionClosed = HandleConnectionClosed;
}

void HandleSecureSessionEstablished(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, uint16_t sessionKeyId, uint64_t peerNodeId, uint8_t encType)
{
    char ipAddrStr[64] = "";

    if (con != NULL)
        con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    printf("Secure session established with node 0x%" PRIx64 " (%s)\n", peerNodeId, ipAddrStr);
}

void HandleSecureSessionError(WeaveSecurityManager *sm, WeaveConnection *con, void *reqState, WEAVE_ERROR localErr, uint64_t peerNodeId, StatusReport *statusReport)
{
    char ipAddrStr[64] = "";

    if (con != NULL)
    {
        con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));
        con->Close();
    }

    if (localErr == WEAVE_ERROR_STATUS_REPORT_RECEIVED && statusReport != NULL)
        printf("FAILED to establish secure session with node 0x%" PRIx64 " (%s): %s\n", peerNodeId, ipAddrStr, nl::StatusReportStr(statusReport->mProfileId, statusReport->mStatusCode));
    else
        printf("FAILED to establish secure session with node 0x%" PRIx64 " (%s): %s\n", peerNodeId, ipAddrStr, ErrorStr(localErr));
}

void HandleConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr)
{
    char ipAddrStr[64];
    // Note: by contract con MUST NOT be NULL, so it is used without the check.
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    if (conErr == WEAVE_NO_ERROR)
        printf("Connection closed to node 0x%" PRIx64 " (%s)\n", con->PeerNodeId, ipAddrStr);
    else
        printf("Connection ABORTED to node 0x%" PRIx64 " (%s): %s\n", con->PeerNodeId, ipAddrStr, ErrorStr(conErr));

    con->Close();
}

/*
 *
 * we may have need of this some day but for now we're not using it and it's
 * generating warnings to that effect.
 *
void HandleConnectionComplete(WeaveConnection *con, WEAVE_ERROR err)
{
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    if (err == WEAVE_NO_ERROR)
    {
        printf("Connection established to %s\n", ipAddrStr);

        ExchangeMgr.AllowUnsolicitedMessages(con);
    }
    else
    {
        printf("Failed to establish connection to %s: %s\n", ipAddrStr, ErrorStr(err));
        con->Close();
    }
}
*
*/
