/*
 *
 *    Copyright (c) 2018 Google LLC.
 *    Copyright (c) 2017-2018 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
 *      Unit tests for Weave Event Logging
 *
 */

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include <new>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include <nlbyteorder.h>
#include <nlunit-test.h>

// 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 "ToolCommon.h"
#include "TestEventLoggingSchemaExamples.h"
#include <InetLayer/Inet.h>
#include <SystemLayer/SystemTimer.h>
#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveMessageLayer.h>
#include <Weave/Core/WeaveEncoding.h>
#include <Weave/Core/WeaveTLV.h>
#include <Weave/Core/WeaveTLVDebug.hpp>
#include <Weave/Core/WeaveTLVUtilities.hpp>
#include <Weave/Core/WeaveTLVData.hpp>
#include <Weave/Core/WeaveSecurityMgr.h>
#include <Weave/Profiles/security/WeaveSecurity.h>
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Profiles/time/WeaveTime.h>

#include <Weave/Support/TraitEventUtils.h>
#include <Weave/Profiles/data-management/DataManagement.h>
#include <Weave/Support/ErrorStr.h>

#include "TestPersistedStorageImplementation.h"
#include <Weave/Support/PersistedCounter.h>

#include "schema/nest/test/trait/TestETrait.h"
#include "schema/nest/test/trait/TestCommon.h"

#include "MockExternalEvents.h"
#include "MockPlatformClocks.h"

using namespace nl::Weave::TLV;
using namespace nl::Weave::Profiles::DataManagement;

namespace Private {

static bool sRealTimeClockValid = true;

System::Error SetClock_RealTime(uint64_t newCurTime)
{
    if (newCurTime != 0)
    {
        sRealTimeClockValid = true;
    }
    else
    {
        sRealTimeClockValid = false;
    }

    return WEAVE_SYSTEM_NO_ERROR;
}

static System::Error GetClock_RealTime(uint64_t & curTime)
{
    if (sRealTimeClockValid)
    {
        curTime = ::nl::Weave::System::Platform::Layer::GetClock_Monotonic();
        return WEAVE_SYSTEM_NO_ERROR;
    }
    else
    {
        curTime = 0;
        return WEAVE_SYSTEM_ERROR_REAL_TIME_NOT_SYNCED;
    }
}

} // namespace Private

namespace nl {
namespace Weave {
namespace Profiles {
namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {
namespace Platform {
// for unit tests, the dummy critical section is sufficient.
void CriticalSectionEnter()
{
    return;
}

void CriticalSectionExit()
{
    return;
}
} // namespace Platform
} // namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)

namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {

class TestSubscriptionHandler : public SubscriptionHandler
{
public:
    TestSubscriptionHandler(void);

    // Make methods from SubscriptionHandler public so we can call them from
    // our test cases.
    using SubscriptionHandler::CheckEventUpToDate;
    using SubscriptionHandler::FindNextImportanceForTransfer;
    using SubscriptionHandler::ParsePathVersionEventLists;
    using SubscriptionHandler::SetEventLogEndpoint;

    bool VerifyTraversingImportance(void);
    nl::Weave::Profiles::DataManagement::event_id_t &
    GetVendedEvent(nl::Weave::Profiles::DataManagement::ImportanceType inImportance);

    void SetActive(void) { mCurrentState = kState_Subscribing_Evaluating; }
    void SetTerminated(void) { mCurrentState = kState_Terminated; }
    void SetEstablishedIdle(void) { mCurrentState = kState_SubscriptionEstablished_Idle; }
    void SetExchangeContext(nl::Weave::ExchangeContext * aEC) { mEC = aEC; }

private:
    /* important: this class must not add any members or declare virtual functions */
};

TestSubscriptionHandler::TestSubscriptionHandler(void)
{
    InitAsFree();
}

bool TestSubscriptionHandler::VerifyTraversingImportance(void)
{
    return FindNextImportanceForTransfer() == nl::Weave::Profiles::DataManagement::kImportanceType_Invalid;
}

nl::Weave::Profiles::DataManagement::event_id_t &
TestSubscriptionHandler::GetVendedEvent(nl::Weave::Profiles::DataManagement::ImportanceType inImportance)
{
    return mSelfVendedEvents[inImportance - nl::Weave::Profiles::DataManagement::kImportanceType_First];
}

SubscriptionEngine * SubscriptionEngine::GetInstance()
{
    static SubscriptionEngine gWdmSubscriptionEngine;

    return &gWdmSubscriptionEngine;
}

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

#define TOOL_NAME "TestDataLogging"

// forward declarations for networking functions.  They are
// implemented at the end of the file, as they are incidental to the
// test and are irrelevant unless the test is invoked in a mode that
// exercises the upload path (i.e. with a dest node ID, or a dest IP
// address.

struct TestLoggingContext;

static void PrepareBinding(TestLoggingContext * context);
static WEAVE_ERROR InitSubscriptionClient(TestLoggingContext * context);
static void HandleBindingEvent(void * const appState, const Binding::EventType event, const Binding::InEventParam & inParam,
                               Binding::OutEventParam & outParam);
static void StartClientConnection(System::Layer * systemLayer, void * appState, System::Error err);
static void HandleConnectionComplete(WeaveConnection * con, WEAVE_ERROR conErr);
static void HandleConnectionClosed(WeaveConnection * con, WEAVE_ERROR conErr);
static WEAVE_ERROR FetchEventsHelper(TLVReader & aReader, event_id_t aEventId, uint8_t * aBackingStore, size_t aLen,
                                     ImportanceType aImportance = nl::Weave::Profiles::DataManagement::Production);

static bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg);

const uint64_t kTestNodeId = 0x18B43000002DCF71ULL;

// Globals used when the test is used in conjunction with BDX

WeaveConnection * Con     = NULL;
bool WaitingForBDXResp    = false;
bool Listening            = false;
bool Upload               = true; // download by default
bool Debug                = false;
uint32_t ConnectInterval  = 200; // ms
uint32_t ConnectTry       = 0;
uint32_t ConnectMaxTry    = 3;
bool ClientConEstablished = false;
bool DestHostNameResolved = false; // only used for UDP

static OptionDef gToolOptionDefs[] = { { "start-event-id", kArgumentRequired, 's' },
                                       { "block-size", kArgumentRequired, 'b' },
                                       { "dest-addr", kArgumentRequired, 'D' },
                                       { "parent-node-id", kArgumentRequired, 'p' },
                                       { "debug", kNoArgument, 'd' },
                                       { "tcp", kNoArgument, 't' },
                                       { "udp", kNoArgument, 'u' },
                                       { NULL } };

static const char * const gToolOptionHelp = "  -p <num>, --parent-node-id <num> \n"
                                            "       Parent node id; the ID of the node that will receive the event\n"
                                            "       logs\n"
                                            "\n"
                                            "  -D <ip-addr>, --dest-addr <ip-addr>\n"
                                            "       The IP address or hostname of the parent (the node that will\n"
                                            "       receive thise event log)\n"
                                            "  -t, --tcp \n"
                                            "       Use TCP for BDX session\n"
                                            "\n"
                                            "  -u, --udp \n"
                                            "       Use UDP for BDX session\n"
                                            "\n"
                                            "  -s <num>, --start-event-id <num>\n"
                                            "       Begin the offload of each event sequence at <num> event\n"
                                            "\n"
                                            "  -b <num>, --block-size <num>\n"
                                            "       Block size to use for BDX upload.\n"
                                            "\n"
                                            "  -d, --debug \n"
                                            "       Enable debug messages.\n"
                                            "\n";

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

static HelpOptions gHelpOptions(TOOL_NAME,
                                "Usage: " TOOL_NAME " [<options...>] <dest-node-id>[@<dest-host>[:<dest-port>][%<interface>]]\n"
                                "       " TOOL_NAME " [<options...>] --listen\n",
                                WEAVE_VERSION_STRING "\n" WEAVE_TOOL_COPYRIGHT,
                                "Test event logging.  Without any options, the program invokes a\n"
                                "suite of local log tests.  The options enable testing of a log\n"
                                "upload over the BDX path.\n");

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

struct BDXContext
{
    uint64_t DestNodeId;
    IPAddress DestIPAddr;
    const char * DestIPAddrStr;
    uint32_t mStartingBlock;
    bool mUseTCP;
    bool mDone;
};

BDXContext gBDXContext;

// Event test harness contex

struct TestLoggingContext
{
    bool mVerbose;
    bool bdx;
    bool bdxDone;
    bool mReinitializeBDXUpload;
    WeaveExchangeManager * mExchangeMgr;
    Binding * mBinding;
    SubscriptionClient * mSubClient;
    TestLoggingContext();
};

TestLoggingContext gTestLoggingContext;

TestLoggingContext::TestLoggingContext() :
    mVerbose(false), bdx(false), bdxDone(false), mReinitializeBDXUpload(false), mExchangeMgr(NULL), mBinding(NULL), mSubClient(NULL)
{ }

LogBDXUpload gLogBDXUpload;

// Example profiles for logging:
#define OpenCloseProfileID 0x235A00AA
#define kOpenCloseStateTag 0x01
#define kBypassStateTag 0x02

enum OpenCloseStateEnum
{
    Unknown       = 0,
    Open          = 1,
    PartiallyOpen = 2,
    Closed        = 3,
};

enum BypassStateEnum
{
    BypassInactive = 0,
    BypassActive   = 1,
    BypassExpired  = 2,
};

struct TestOpenCloseState
{
    TestOpenCloseState();
    void EvolveState();
    uint8_t mState;
    uint8_t mBypass;
};

TestOpenCloseState gTestOpenCloseState;

TestOpenCloseState::TestOpenCloseState()
{
    mState  = Closed;
    mBypass = BypassInactive;
}

void TestOpenCloseState::EvolveState(void)
{
    if (mState == Closed)
    {
        mState = Open;
    }
    else
    {
        mState = Closed;
    }
}

WEAVE_ERROR WriteOpenCloseState(nl::Weave::TLV::TLVWriter & writer, uint8_t inDataTag, void * anAppState)
{
    TestOpenCloseState * state = NULL;
    WEAVE_ERROR err            = WEAVE_NO_ERROR;
    nl::Weave::TLV::TLVType openCloseState;

    VerifyOrExit(anAppState != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    state = static_cast<TestOpenCloseState *>(anAppState);

    err = writer.StartContainer(ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventData), nl::Weave::TLV::kTLVType_Structure,
                                openCloseState);
    SuccessOrExit(err);

    err = writer.Put(nl::Weave::TLV::ContextTag(kOpenCloseStateTag), state->mState);
    SuccessOrExit(err);

    err = writer.Put(nl::Weave::TLV::ContextTag(kBypassStateTag), state->mBypass);
    SuccessOrExit(err);

    err = writer.EndContainer(openCloseState);
    SuccessOrExit(err);

    err = writer.Finalize();

    state->EvolveState();

exit:
    return err;
}

void SimpleDumpWriter(const char * aFormat, ...)
{
    va_list args;

    va_start(args, aFormat);

    vprintf(aFormat, args);

    va_end(args);
}

WEAVE_ERROR LogBufferConsole(void * inAppState, PacketBuffer * inBuffer)
{
    printf("Log entries:\nTime\tSchema\tEventData\n");
    nl::Weave::TLV::TLVReader reader;
    uint8_t * p     = inBuffer->Start();
    uint32_t time   = *((uint32_t *) p);
    uint16_t schema = *((uint16_t *) (p + 4));

    inBuffer->SetStart(p + 6);

    reader.Init(inBuffer, inBuffer->TotalLength());
    printf("%d\t%d\t", time, schema);
    nl::Weave::TLV::Debug::Dump(reader, SimpleDumpWriter);
    return WEAVE_NO_ERROR;
}

// Maximally sized event envelope
#define EVENT_ENVELOPE_SIZE 26
// Larger event payload. structured s.t. it fits in within the
// WEAVE_CONFIG_EVENT_SIZE_RESERVE (with the envelope)
#define EVENT_PAYLOAD_SIZE_1 128
// Larger event payload.  Structured s.t. it fits in the buffer, but
// it is larger than the WEAVE_CONFIG_SIZE_RESERVE
#define EVENT_PAYLOAD_SIZE_2 256
#define EVENT_SIZE_1 EVENT_PAYLOAD_SIZE_1 + EVENT_ENVELOPE_SIZE
// Larger event payload.  Doesn't fit in debug buffer.
#define EVENT_PAYLOAD_SIZE_3 (WEAVE_CONFIG_EVENT_SIZE_RESERVE + EVENT_SIZE_1)

uint64_t gDebugEventBuffer[(sizeof(nl::Weave::Profiles::DataManagement::CircularEventBuffer) + WEAVE_CONFIG_EVENT_SIZE_RESERVE +
                            EVENT_SIZE_1 + 7) /
                           8];
uint64_t gInfoEventBuffer[256];
uint64_t gProdEventBuffer[256];
uint64_t gCritEventBuffer[256];
uint8_t gLargeMemoryBackingStore[16384];

static const uint32_t sEventIdCounterEpoch = 0x10000;

static const char * sCritEventIdCounterStorageKey = "CritEIDC";
static nl::Weave::PersistedCounter sCritEventIdCounter;
static const char * sProductionEventIdCounterStorageKey = "ProductionEIDC";
static nl::Weave::PersistedCounter sProductionEventIdCounter;
static const char * sInfoEventIdCounterStorageKey = "InfoEIDC";
static nl::Weave::PersistedCounter sInfoEventIdCounter;
static const char * sDebugEventIdCounterStorageKey = "DebugEIDC";
static nl::Weave::PersistedCounter sDebugEventIdCounter;

void InitializeEventLogging(TestLoggingContext * context)
{
    LogStorageResources logStorageResources[] = { { static_cast<void *>(&gCritEventBuffer[0]), sizeof(gCritEventBuffer), NULL, 0,
                                                    NULL, nl::Weave::Profiles::DataManagement::ImportanceType::ProductionCritical },
                                                  { static_cast<void *>(&gProdEventBuffer[0]), sizeof(gProdEventBuffer), NULL, 0,
                                                    NULL, nl::Weave::Profiles::DataManagement::ImportanceType::Production },
                                                  { static_cast<void *>(&gInfoEventBuffer[0]), sizeof(gInfoEventBuffer), NULL, 0,
                                                    NULL, nl::Weave::Profiles::DataManagement::ImportanceType::Info },
                                                  { static_cast<void *>(&gDebugEventBuffer[0]), sizeof(gDebugEventBuffer), NULL, 0,
                                                    NULL, nl::Weave::Profiles::DataManagement::ImportanceType::Debug } };

    nl::Weave::Profiles::DataManagement::LoggingManagement::CreateLoggingManagement(
        context->mExchangeMgr, sizeof(logStorageResources) / sizeof(logStorageResources[0]), logStorageResources);
    nl::Weave::Profiles::DataManagement::LoggingManagement & instance =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();
    nl::Weave::Profiles::DataManagement::LoggingConfiguration::GetInstance().mGlobalImportance =
        nl::Weave::Profiles::DataManagement::Debug;
    new (&gLogBDXUpload) nl::Weave::Profiles::DataManagement::LogBDXUpload();
    gLogBDXUpload.Init(&instance);
}

void DestroyEventLogging(TestLoggingContext * context)
{
    nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().DestroyLoggingManagement();
}

void InitializeEventLoggingWithPersistedCounters(TestLoggingContext * context, uint32_t startingValue,
                                                 nl::Weave::Profiles::DataManagement::ImportanceType globalImportance)
{
    LogStorageResources logStorageResources[] = {
        { static_cast<void *>(&gCritEventBuffer[0]), sizeof(gCritEventBuffer), &sCritEventIdCounterStorageKey, sEventIdCounterEpoch,
          &sCritEventIdCounter, nl::Weave::Profiles::DataManagement::ImportanceType::ProductionCritical },
        { static_cast<void *>(&gProdEventBuffer[0]), sizeof(gProdEventBuffer), &sProductionEventIdCounterStorageKey,
          sEventIdCounterEpoch, &sProductionEventIdCounter, nl::Weave::Profiles::DataManagement::ImportanceType::Production },
        { static_cast<void *>(&gInfoEventBuffer[0]), sizeof(gInfoEventBuffer), &sInfoEventIdCounterStorageKey, sEventIdCounterEpoch,
          &sInfoEventIdCounter, nl::Weave::Profiles::DataManagement::ImportanceType::Info },
        { static_cast<void *>(&gDebugEventBuffer[0]), sizeof(gDebugEventBuffer), &sDebugEventIdCounterStorageKey,
          sEventIdCounterEpoch, &sDebugEventIdCounter, nl::Weave::Profiles::DataManagement::ImportanceType::Debug }
    };

    nl::Weave::Platform::PersistedStorage::Write(sCritEventIdCounterStorageKey, startingValue);
    nl::Weave::Platform::PersistedStorage::Write(sProductionEventIdCounterStorageKey, startingValue);
    nl::Weave::Platform::PersistedStorage::Write(sInfoEventIdCounterStorageKey, startingValue);
    nl::Weave::Platform::PersistedStorage::Write(sDebugEventIdCounterStorageKey, startingValue);

    nl::Weave::Profiles::DataManagement::LoggingManagement::CreateLoggingManagement(
        context->mExchangeMgr, sizeof(logStorageResources) / sizeof(logStorageResources[0]), logStorageResources);

    nl::Weave::Profiles::DataManagement::LoggingConfiguration::GetInstance().mGlobalImportance = globalImportance;
}

void DumpEventLog(nlTestSuite * inSuite)
{
    uint8_t backingStore[1024];
    size_t elementCount;
    event_id_t eventId = 1;
    TLVWriter writer;
    TLVReader reader;
    WEAVE_ERROR err;
    writer.Init(backingStore, 1024);

    err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
        writer, nl::Weave::Profiles::DataManagement::Production, eventId);
    if (err == WEAVE_NO_ERROR || err == WEAVE_END_OF_TLV)
    {
        printf("Successfully wrote %u bytes to the log\n", writer.GetLengthWritten());
    }
    else
    {
        printf("Wrote %u bytes to the log, FetchEventsSince returned %s (%d)\n", writer.GetLengthWritten(), ErrorStr(err), err);
    }
    reader.Init(backingStore, 1024);
    nl::Weave::TLV::Utilities::Count(reader, elementCount);
    printf("Fetched %zu elements, last eventID: %u \n", elementCount, eventId);
    nl::Weave::TLV::Debug::Dump(reader, SimpleDumpWriter);
}

void DoBDXUpload(TestLoggingContext * context)
{
    if (!context->bdx)
    {
        return;
    }
    gBDXContext.mDone = false;
    if (gBDXContext.mUseTCP)
    {
        SystemLayer.StartTimer(ConnectInterval, StartClientConnection, &gBDXContext);
    }
    else
    {
        PrepareBinding(context);
    }

    while (!gBDXContext.mDone)
    {
        struct timeval sleepTime;
        sleepTime.tv_sec  = 0;
        sleepTime.tv_usec = 100000;

        ServiceNetwork(sleepTime);
        if (gLogBDXUpload.mState == nl::Weave::Profiles::DataManagement::LogBDXUpload::UploaderInitialized)
        {
            gBDXContext.mDone = true;
            for (size_t i = 0; i < 1000; i++)
            {
                sleepTime.tv_sec  = 0;
                sleepTime.tv_usec = 1000;

                ServiceNetwork(sleepTime);
            }
        }
    }

    gLogBDXUpload.Shutdown();
}

void PrintEventLog()
{
    TLVReader reader;
    size_t elementCount;
    nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().GetEventReader(
        reader, nl::Weave::Profiles::DataManagement::Production);

    nl::Weave::TLV::Utilities::Count(reader, elementCount);
    printf("Found %lu elements\n", elementCount);
    nl::Weave::TLV::Debug::Dump(reader, SimpleDumpWriter);
}

static int TestSetup(void * inContext)
{
    TestLoggingContext * ctx = static_cast<TestLoggingContext *>(inContext);
    static WeaveFabricState sFabricState;
    static WeaveExchangeManager sExchangeMgr;

    InitSystemLayer();

    if (ctx->bdx)
    {
        InitNetwork();
        InitWeaveStack(true, true);

        ctx->mExchangeMgr = &ExchangeMgr;
    }
    else
    {
        // fake Weave exchange layer.  We are not running any
        // networking tests, and at that point the only functionality
        // required by the event logging subsystem is that the
        // ExchageManager has a fabric state with a node id.

        WEAVE_ERROR err = WEAVE_NO_ERROR;
#if WEAVE_SYSTEM_CONFIG_USE_LWIP
        tcpip_init(NULL, NULL);
#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP

        err = sFabricState.Init();
        if (err != WEAVE_NO_ERROR)
            return FAILURE;

        sFabricState.LocalNodeId = kTestNodeId;
        sExchangeMgr.FabricState = &sFabricState;
        sExchangeMgr.State       = WeaveExchangeManager::kState_Initialized;
        ctx->mExchangeMgr        = &sExchangeMgr;
    }

    SubscriptionEngine::GetInstance()->Init(&ExchangeMgr, NULL, NULL);

    return SUCCESS;
}

static int TestTeardown(void * inContext)
{
    TestLoggingContext * ctx = static_cast<TestLoggingContext *>(inContext);
    if (ctx->bdx)
    {
        ShutdownWeaveStack();
        ShutdownNetwork();
    }

    ShutdownSystemLayer();
    return SUCCESS;
}

static void CheckLogState(nlTestSuite * inSuite, TestLoggingContext * inContext,
                          nl::Weave::Profiles::DataManagement::LoggingManagement & logMgmt, size_t expectedNumEvents)
{
    WEAVE_ERROR err;
    TLVReader reader;
    size_t elementCount;

    err = logMgmt.GetEventReader(reader, nl::Weave::Profiles::DataManagement::Production);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = nl::Weave::TLV::Utilities::Count(reader, elementCount, false);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, elementCount == expectedNumEvents);
    if (inContext->mVerbose)
    {
        printf("Num Events: %lu\n", elementCount);
    }
}

static void CheckLogReadOut(nlTestSuite * inSuite, TestLoggingContext * inContext,
                            nl::Weave::Profiles::DataManagement::LoggingManagement & logMgmt,
                            nl::Weave::Profiles::DataManagement::ImportanceType importance, event_id_t startingEventId,
                            size_t expectedNumEvents)
{
    WEAVE_ERROR err;
    TLVReader reader;
    TLVWriter writer;
    uint8_t backingStore[1024];
    size_t elementCount;
    writer.Init(backingStore, 1024);

    err = logMgmt.FetchEventsSince(writer, importance, startingEventId);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR || err == WEAVE_END_OF_TLV);

    reader.Init(backingStore, writer.GetLengthWritten());

    err = nl::Weave::TLV::Utilities::Count(reader, elementCount, false);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, elementCount == expectedNumEvents);

    if (inContext->mVerbose)
    {
        reader.Init(backingStore, writer.GetLengthWritten());
        printf("Starting Event ID: %u, Expected Events: %lu, Num Events: %lu, Num Bytes: %u\n", startingEventId, expectedNumEvents,
               elementCount, writer.GetLengthWritten());
        nl::Weave::TLV::Debug::Dump(reader, SimpleDumpWriter);
    }
}

static void CheckLogEventBasics(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    event_id_t eid1, eid2, eid3;
    EventSchema schema = { OpenCloseProfileID,
                           1, // Event type 1
                           nl::Weave::Profiles::DataManagement::Production, 1, 1 };

    InitializeEventLogging(context);

    nl::Weave::Profiles::DataManagement::LoggingManagement & logMgmt =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    // Sample production events, spaced 10 milliseconds apart
    eid1 = nl::Weave::Profiles::DataManagement::LogEvent(schema, WriteOpenCloseState, static_cast<void *>(&gTestOpenCloseState));
    CheckLogState(inSuite, context, logMgmt, 1);

    usleep(10000);
    eid2 = nl::Weave::Profiles::DataManagement::LogEvent(schema, WriteOpenCloseState, static_cast<void *>(&gTestOpenCloseState));
    CheckLogState(inSuite, context, logMgmt, 2);

    usleep(10000);
    eid3 = nl::Weave::Profiles::DataManagement::LogEvent(schema, WriteOpenCloseState, static_cast<void *>(&gTestOpenCloseState));
    CheckLogState(inSuite, context, logMgmt, 3);

    if (context->mVerbose)
    {
        PrintEventLog();
    }
    NL_TEST_ASSERT(inSuite, (eid1 + 1) == eid2);
    NL_TEST_ASSERT(inSuite, (eid2 + 1) == eid3);

    // Verify that the readout supports the expected volume of events
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid1, 3);
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid2, 2);
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid3, 1);
    if (context->bdx)
    {
        DoBDXUpload(context);
    }
}

static void CheckLogFreeform(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    event_id_t eid1, eid2, eid3;
    size_t counter = 0;
    InitializeEventLogging(context);

    nl::Weave::Profiles::DataManagement::LoggingManagement & logMgmt =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    // Sample production events, spaced 10 milliseconds apart
    eid1 = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production, "Freeform entry %d",
                                                            counter++);

    CheckLogState(inSuite, context, logMgmt, 1);

    usleep(10000);

    eid2 = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production, "Freeform entry %d",
                                                            counter++);
    CheckLogState(inSuite, context, logMgmt, 2);

    usleep(10000);
    eid3 = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production, "Freeform entry %d",
                                                            counter++);
    CheckLogState(inSuite, context, logMgmt, 3);

    if (context->mVerbose)
    {
        PrintEventLog();
    }
    NL_TEST_ASSERT(inSuite, (eid1 + 1) == eid2);
    NL_TEST_ASSERT(inSuite, (eid2 + 1) == eid3);

    // Verify that the readout supports the expected volume of events
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid1, 3);
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid2, 2);
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid3, 1);
    if (context->bdx)
    {
        DoBDXUpload(context);
    }
}

static void CheckLogPreformed(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;
    event_id_t eid1, eid2, eid3;
    EventSchema schema = { OpenCloseProfileID,
                           2, // Event type 2
                           nl::Weave::Profiles::DataManagement::Production, 1, 1 };

    uint8_t backingStore[1024];
    TLVWriter writer;
    TLVType containerType;
    TLVReader reader;

    InitializeEventLogging(context);

    nl::Weave::Profiles::DataManagement::LoggingManagement & logMgmt =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    writer.Init(backingStore, 1024);
    err = writer.StartContainer(AnonymousTag, kTLVType_Structure, containerType);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = writer.Put(ContextTag(1), false);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = writer.Put(ContextTag(2), true);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = writer.EndContainer(containerType);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = writer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    reader.Init(backingStore, writer.GetLengthWritten());

    // Sample production events, spaced 10 milliseconds apart
    eid1 = nl::Weave::Profiles::DataManagement::LogEvent(schema, reader);

    CheckLogState(inSuite, context, logMgmt, 1);

    usleep(10000);
    reader.Init(backingStore, writer.GetLengthWritten());
    eid2 = nl::Weave::Profiles::DataManagement::LogEvent(schema, reader);
    CheckLogState(inSuite, context, logMgmt, 2);

    usleep(10000);
    reader.Init(backingStore, writer.GetLengthWritten());
    eid3 = nl::Weave::Profiles::DataManagement::LogEvent(schema, reader);
    CheckLogState(inSuite, context, logMgmt, 3);

    if (context->mVerbose)
    {
        PrintEventLog();
    }
    NL_TEST_ASSERT(inSuite, (eid1 + 1) == eid2);
    NL_TEST_ASSERT(inSuite, (eid2 + 1) == eid3);

    // Verify that the readout supports the expected volume of events
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid1, 3);
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid2, 2);
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid3, 1);
    if (context->bdx)
    {
        DoBDXUpload(context);
    }
}

#define kSampleEventTag_State 1
#define kSampleEventTag_Timestamp 2
#define kSampleEventTag_Structure 3
#define kSampleEventTag_Samples 4

#define kEventStructTag_a 1
#define kEventStructTag_b 2

#define kEventStatsTag_str 1

#define kDataManagementTag_EventData 50

static const uint8_t SampleEventEncoding[] = { nlWeaveTLV_STRUCTURE(nlWeaveTLV_TAG_FULLY_QUALIFIED_6Bytes(0x0A00, 1)),
                                               nlWeaveTLV_STRUCTURE(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kDataManagementTag_EventData)),
                                               nlWeaveTLV_UINT8(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kSampleEventTag_State), 5),
                                               nlWeaveTLV_UINT16(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kSampleEventTag_Timestamp), 328),
                                               nlWeaveTLV_STRUCTURE(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kSampleEventTag_Structure)),
                                               nlWeaveTLV_BOOL(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kEventStructTag_a), true),
                                               nlWeaveTLV_STRUCTURE(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kEventStructTag_b)),
                                               nlWeaveTLV_UTF8_STRING_1ByteLength(
                                                   nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kEventStatsTag_str), 10),
                                               'b',
                                               'l',
                                               'o',
                                               'o',
                                               'p',
                                               'b',
                                               'l',
                                               'o',
                                               'o',
                                               'p',
                                               nlWeaveTLV_END_OF_CONTAINER,
                                               nlWeaveTLV_END_OF_CONTAINER,
                                               nlWeaveTLV_ARRAY(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kSampleEventTag_Samples)),
                                               nlWeaveTLV_UINT8(nlWeaveTLV_TAG_ANONYMOUS, 0),
                                               nlWeaveTLV_UINT8(nlWeaveTLV_TAG_ANONYMOUS, 1),
                                               nlWeaveTLV_UINT8(nlWeaveTLV_TAG_ANONYMOUS, 2),
                                               nlWeaveTLV_UINT8(nlWeaveTLV_TAG_ANONYMOUS, 3),
                                               nlWeaveTLV_UINT8(nlWeaveTLV_TAG_ANONYMOUS, 4),
                                               nlWeaveTLV_UINT8(nlWeaveTLV_TAG_ANONYMOUS, 5),
                                               nlWeaveTLV_END_OF_CONTAINER,
                                               nlWeaveTLV_END_OF_CONTAINER,
                                               nlWeaveTLV_END_OF_CONTAINER };

static const uint8_t SampleEmptyArrayEventEncoding[] = {
    nlWeaveTLV_STRUCTURE(nlWeaveTLV_TAG_FULLY_QUALIFIED_6Bytes(0x0A00, 1)),
    nlWeaveTLV_STRUCTURE(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kDataManagementTag_EventData)),
    nlWeaveTLV_UINT8(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kSampleEventTag_State), 5),
    nlWeaveTLV_UINT16(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kSampleEventTag_Timestamp), 328),
    nlWeaveTLV_STRUCTURE(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kSampleEventTag_Structure)),
    nlWeaveTLV_BOOL(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kEventStructTag_a), true),
    nlWeaveTLV_STRUCTURE(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kEventStructTag_b)),
    nlWeaveTLV_UTF8_STRING_1ByteLength(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kEventStatsTag_str), 10),
    'b',
    'l',
    'o',
    'o',
    'p',
    'b',
    'l',
    'o',
    'o',
    'p',
    nlWeaveTLV_END_OF_CONTAINER,
    nlWeaveTLV_END_OF_CONTAINER,
    nlWeaveTLV_ARRAY(nlWeaveTLV_TAG_CONTEXT_SPECIFIC(kSampleEventTag_Samples)),
    nlWeaveTLV_END_OF_CONTAINER,
    nlWeaveTLV_END_OF_CONTAINER,
    nlWeaveTLV_END_OF_CONTAINER
};

static void CheckSchemaGeneratedLogging(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    event_id_t eid1, eid2;
    WEAVE_ERROR err;
    nl::Weave::Profiles::DataManagement::LoggingManagement & logMgmt =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    nl::Weave::Profiles::DataManagement::SampleTrait::Event ev;
    nl::Weave::Profiles::DataManagement::OpenCloseTrait::Event ev2;
    nl::StructureSchemaPointerPair appData;
    nl::Weave::TLV::TLVWriter outer, writer;
    uint8_t sBuffer[256];

    InitializeEventLogging(context);

    uint32_t samples[6]    = { 0, 1, 2, 3, 4, 5 };
    ev.state               = 5;
    ev.timestamp           = 328;
    ev.structure.a         = true;
    ev.structure.b.str     = "bloopbloop\0";
    ev.samples.num_samples = 6;
    ev.samples.samples_buf = samples;

    appData.mStructureData = static_cast<void *>(&ev);
    appData.mFieldSchema   = &sampleEventSchema;

    outer.Init(sBuffer, sizeof(sBuffer));

    err = outer.OpenContainer(ProfileTag(0x0A00, 1), kTLVType_Structure, writer);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = SerializedDataToTLVWriterHelper(writer, kTag_EventData, &appData);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = writer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outer.CloseContainer(writer);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    // Verify the encoding

    NL_TEST_ASSERT(inSuite, outer.GetLengthWritten() == sizeof(SampleEventEncoding));
    NL_TEST_ASSERT(inSuite, memcmp(sBuffer, SampleEventEncoding, sizeof(SampleEventEncoding)) == 0);

    eid1 = LogSampleEvent(&ev, nl::Weave::Profiles::DataManagement::Production);
    CheckLogState(inSuite, context, logMgmt, 1);

    ev2.state = 1;
    eid2      = LogOpenCloseEvent(&ev2, nl::Weave::Profiles::DataManagement::Production);
    CheckLogState(inSuite, context, logMgmt, 2);

    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid1, 2);
    CheckLogReadOut(inSuite, context, logMgmt, nl::Weave::Profiles::DataManagement::Production, eid2, 1);

    if (context->bdx)
    {
        DoBDXUpload(context);
    }
}

static void CheckByteStringFieldType(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;
    event_id_t eventId;
    ByteStringTestTrait::Event ev, deserializedEv;
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;

    TLVReader testReader;
    uint8_t buf[10];
    ev.byte_string.mLen = sizeof(buf);
    ev.byte_string.mBuf = buf;
    memset(buf, 0xaa, 10);

    InitializeEventLogging(context);

    eventId = LogByteStringTestEvent(&ev);

    err = FetchEventsHelper(testReader, eventId, gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = DeserializeByteStringTestEvent(testReader, &deserializedEv, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, deserializedEv.byte_string.mLen == ev.byte_string.mLen);
    NL_TEST_ASSERT(inSuite, memcmp(deserializedEv.byte_string.mBuf, ev.byte_string.mBuf, ev.byte_string.mLen) == 0);
}

static void CheckByteStringArray(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;
    event_id_t eventId;
    ByteStringArrayTestTrait::Event ev, deserializedEv;
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;

    TLVReader testReader;
    nl::SerializedByteString bytestrings[5];
    uint8_t buf[100];
    int i;

    // some magic numbers to initialize some varied byte strings
    for (i = 0; i < 5; i++)
    {
        memset(&buf[i * 5], (i + 1) * 40, (i + 1) * 5);
        bytestrings[i].mLen = (i + 1) * 5;
        bytestrings[i].mBuf = &buf[i * 5];
    }
    ev.testArray.num = 5;
    ev.testArray.buf = bytestrings;

    InitializeEventLogging(context);

    eventId = LogByteStringArrayTestEvent(&ev);

    err = FetchEventsHelper(testReader, eventId, gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = DeserializeByteStringArrayTestEvent(testReader, &deserializedEv, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, deserializedEv.testArray.num == ev.testArray.num);
    for (i = 0; i < 5; i++)
    {
        NL_TEST_ASSERT(inSuite, deserializedEv.testArray.buf[i].mLen == ev.testArray.buf[i].mLen);
        NL_TEST_ASSERT(inSuite,
                       memcmp(deserializedEv.testArray.buf[i].mBuf, ev.testArray.buf[i].mBuf, ev.testArray.buf[i].mLen) == 0);
    }
}

struct DebugLogContext
{
    const char * mRegion;
    const char * mFmt;
    va_list mArgs;
};

static event_id_t FastLogFreeform(ImportanceType inImportance, timestamp_t inTimestamp, const char * inFormat, ...)
{
    DebugLogContext context;
    nl::Weave::Profiles::DataManagement::EventOptions options;
    event_id_t eid;
    EventSchema schema = { kWeaveProfile_NestDebug, kNestDebug_StringLogEntryEvent, inImportance, 1, 1 };

    va_start(context.mArgs, inFormat);
    context.mRegion = "";
    context.mFmt    = inFormat;

    options = EventOptions(inTimestamp, NULL, 0, nl::Weave::Profiles::DataManagement::kImportanceType_Invalid, false);

    eid = LogEvent(schema, PlainTextWriter, &context, &options);

    va_end(context.mArgs);

    return eid;
}

static void CheckEvict(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    event_id_t eid_prev, eid;
    size_t counter = 0;
    timestamp_t now;
    InitializeEventLogging(context);

    now      = System::Layer::GetClock_MonotonicMS();
    eid_prev = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);
    now += 10;
    for (counter = 0; counter < 100; counter++)
    {
        // Sample production events, spaced 10 milliseconds apart
        eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);
        now += 10;

        NL_TEST_ASSERT(inSuite, eid > 0);
        NL_TEST_ASSERT(inSuite, eid == (eid_prev + 1));

        eid_prev = eid;
    }
    if (context->bdx)
    {
        DoBDXUpload(context);
    }
}

static WEAVE_ERROR ReadFirstEventHeader(TLVReader & aReader, timestamp_t & aTimestamp, utc_timestamp_t & aUtcTimestamp,
                                        event_id_t & aEventId)
{
    WEAVE_ERROR err;
    TLVType readerType;
    uint64_t currentContextTag;

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

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

    currentContextTag = aReader.GetTag();

    while ((currentContextTag != ContextTag(kTag_EventData)) && !err)
    {
        if (currentContextTag == ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventSystemTimestamp))
        {
            err = aReader.Get(aTimestamp);
            SuccessOrExit(err);
        }

        if (currentContextTag == ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventUTCTimestamp))
        {
            err = aReader.Get(aUtcTimestamp);
            SuccessOrExit(err);
        }

        if (currentContextTag == ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventID))
        {
            err = aReader.Get(aEventId);
            SuccessOrExit(err);
        }

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

        currentContextTag = aReader.GetTag();
    }

    err = aReader.ExitContainer(readerType);

exit:
    return err;
}

static void CheckFetchTimestamps(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    event_id_t eid_prev, eid, event_id_read;
    size_t counter         = 0;
    const int k_num_events = 10;
    timestamp_t now;
    utc_timestamp_t test_start;
    InitializeEventLogging(context);

    test_start = static_cast<utc_timestamp_t>(System::Layer::GetClock_MonotonicMS());
    now        = static_cast<timestamp_t>(test_start);
    System::Layer::SetClock_RealTime(0);

    eid_prev = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "%u", now);
    eid_prev = FastLogFreeform(nl::Weave::Profiles::DataManagement::Info, now, "%u", now);
    now += 10;
    for (counter = 1; counter < k_num_events; counter++)
    {
        // Sample production events, spaced 10 milliseconds apart
        if (counter == k_num_events / 2)
        {
            System::Layer::SetClock_RealTime((test_start) *1000);
        }

        eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Info, now, "%u", now);
        NL_TEST_ASSERT(inSuite, eid > 0);
        eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "%u", now);

        NL_TEST_ASSERT(inSuite, eid > 0);
        NL_TEST_ASSERT(inSuite, eid == (eid_prev + 1));

        now += 10;
        eid_prev = eid;
    }

    NL_TEST_ASSERT(inSuite, eid_prev == k_num_events);

    for (counter = 0; counter < k_num_events; counter++)
    {
        TLVReader testReader;
        TLVWriter testWriter;
        utc_timestamp_t testUtcTimestamp = 0;
        timestamp_t testTimestamp        = 0;
        event_id_t testEventID           = 0;

        event_id_read = counter + 1;
        testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
        err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
            testWriter, nl::Weave::Profiles::DataManagement::Info, event_id_read);
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV);
        NL_TEST_ASSERT(inSuite, event_id_read == eid_prev + 1);

        if (context->mVerbose)
        {
            TLVReader reader;
            reader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());

            nl::Weave::TLV::Debug::Dump(reader, SimpleDumpWriter);
        }

        testReader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());

        err = ReadFirstEventHeader(testReader, testTimestamp, testUtcTimestamp, testEventID);

        NL_TEST_ASSERT(inSuite, testEventID == counter + 1);
        NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
#if WEAVE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS
        if (counter >= k_num_events / 2)
        {
            NL_TEST_ASSERT(inSuite, testUtcTimestamp == test_start + (testEventID - 1) * 10);
        }
        else
#endif // WEAVE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS
        {
            NL_TEST_ASSERT(inSuite, testTimestamp == static_cast<timestamp_t>(test_start) + (testEventID - 1) * 10);
        }
    }
}

WEAVE_ERROR WriteLargeEvent(nl::Weave::TLV::TLVWriter & writer, uint8_t inDataTag, void * anAppState)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    nl::Weave::TLV::TLVType containerType;
    uint32_t * payloadEventSize;
    uint8_t * dummyPayload = NULL;

    VerifyOrExit(anAppState != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    payloadEventSize = static_cast<uint32_t *>(anAppState);

    dummyPayload = reinterpret_cast<uint8_t *>(malloc(*payloadEventSize));
    VerifyOrExit(dummyPayload != NULL, err = WEAVE_ERROR_NO_MEMORY);

    memset(dummyPayload, 0xa5, *payloadEventSize);

    err = writer.StartContainer(ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventData), nl::Weave::TLV::kTLVType_Structure,
                                containerType);
    SuccessOrExit(err);

    err = writer.PutBytes(nl::Weave::TLV::ContextTag(1), dummyPayload, *payloadEventSize);
    SuccessOrExit(err);

    err = writer.EndContainer(containerType);
    SuccessOrExit(err);

    err = writer.Finalize();

exit:
    if (dummyPayload != NULL)
    {
        free(dummyPayload);
    }
    return err;
}

static void CheckLargeEvents(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    uint32_t payloadSize;
    event_id_t eid1, eid2, eid3, eid4;
    EventSchema schema = { OpenCloseProfileID,
                           1, // Event type 1
                           nl::Weave::Profiles::DataManagement::Production, 1, 1 };

    InitializeEventLogging(context);

    nl::Weave::Profiles::DataManagement::LoggingManagement & logMgmt =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    // we expect this payload to succeed
    payloadSize = EVENT_PAYLOAD_SIZE_1;
    eid1        = nl::Weave::Profiles::DataManagement::LogEvent(schema, WriteLargeEvent, static_cast<void *>(&payloadSize));
    NL_TEST_ASSERT(inSuite, eid1 == 1);

    eid2 = nl::Weave::Profiles::DataManagement::LogEvent(schema, WriteLargeEvent, static_cast<void *>(&payloadSize));
    NL_TEST_ASSERT(inSuite, eid2 == 2);
    CheckLogState(inSuite, context, logMgmt, 2);

    // new test case - events will get retried if they fail
    payloadSize = EVENT_PAYLOAD_SIZE_2;
    eid3        = nl::Weave::Profiles::DataManagement::LogEvent(schema, WriteLargeEvent, static_cast<void *>(&payloadSize));
    NL_TEST_ASSERT(inSuite, eid3 == 3);

    // this event is wider than the debug buffer
    payloadSize = EVENT_PAYLOAD_SIZE_3;
    eid4        = nl::Weave::Profiles::DataManagement::LogEvent(schema, WriteLargeEvent, static_cast<void *>(&payloadSize));
    NL_TEST_ASSERT(inSuite, eid4 == 0);
}

#if WEAVE_CONFIG_EVENT_LOGGING_EXTERNAL_EVENT_SUPPORT
static void CheckDropEvents(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err;
    int counter                  = 0;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    EventSchema schema           = { OpenCloseProfileID,
                           1, // Event type 1
                           nl::Weave::Profiles::DataManagement::Production, 1, 1 };
    event_id_t eid_prev, eid;
    CircularEventBuffer * prodBuf = reinterpret_cast<CircularEventBuffer *>(&gProdEventBuffer[0]);
    uint32_t eventSizes[]         = {
        EVENT_ENVELOPE_SIZE,
        EVENT_PAYLOAD_SIZE_1,
        EVENT_PAYLOAD_SIZE_2,
    };
    const uint32_t numSizes = sizeof(eventSizes) / sizeof(uint32_t);
    TLVWriter testWriter;

    InitializeEventLogging(context);

    nl::Weave::Profiles::DataManagement::LoggingManagement & logMgmt =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    // register some fake events
    err = LogMockExternalEvents(10, 1);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    eid_prev = prodBuf->mLastEventID;

    while (prodBuf->mFirstEventID <= 10)
    {
        eid = nl::Weave::Profiles::DataManagement::LogEvent(schema, WriteLargeEvent,
                                                            static_cast<void *>(&eventSizes[counter++ % numSizes]));
        NL_TEST_ASSERT(inSuite, eid > eid_prev);

        if (eid_prev > 10)
        {
            testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
            err = logMgmt.FetchEventsSince(testWriter, nl::Weave::Profiles::DataManagement::Production, eid_prev);
            NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV);
            NL_TEST_ASSERT(inSuite, eid_prev == eid + 1);
        }

        eid_prev = eid;
    }

    {
        TLVReader testReader;
        event_id_t testEventID, eid_in = 0;
        timestamp_t testTimestamp;
        utc_timestamp_t testUtcTimestamp;

        testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
        err = logMgmt.FetchEventsSince(testWriter, nl::Weave::Profiles::DataManagement::Production, eid_in);
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV);
        NL_TEST_ASSERT(inSuite, eid_in > 10);

        testReader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());
        err = ReadFirstEventHeader(testReader, testTimestamp, testUtcTimestamp, testEventID);
        NL_TEST_ASSERT(inSuite, testEventID >= 10);
    }
}

#endif // WEAVE_CONFIG_EVENT_LOGGING_EXTERNAL_EVENT_SUPPORT

static void CheckFetchEvents(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    event_id_t eid_prev, eid, eventId;
    size_t counter = 0;
    // small buffer, sized s.t. the events generated below will be
    // larger than a single buffer, but smaller than two buffers.
    uint8_t smallMemoryBackingStore[1280];
    PacketBuffer * pbuf = PacketBuffer::New();
    TLVWriter testWriter;
    WEAVE_ERROR err;
    timestamp_t now;
    InitializeEventLogging(context);
    now = static_cast<timestamp_t>(0);

    eid_prev = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);

    // The magic number "40" below is selected to be large enough to
    // generate more events than can fit in a single PacketBuffer, but
    // fewer than can fit in 2 packet buffers.  This ensures that we
    // test both the cases when we run out of log before ending the
    // buffer, and the cases when the writer runs out of space before
    // the end of the log.
    now += 10;
    for (counter = 0; counter < 40; counter++)
    {
        // Sample production events, spaced 10 milliseconds apart
        eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);
        now += 10;

        NL_TEST_ASSERT(inSuite, eid > 0);
        NL_TEST_ASSERT(inSuite, eid == (eid_prev + 1));

        eid_prev = eid;
    }

    if (context->mVerbose)
    {
        PrintEventLog();
    }

    // Test that offloading events into large buffer completes and
    // returns WEAVE_END_OF_TLV
    eventId = 0;
    testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
    err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
        testWriter, nl::Weave::Profiles::DataManagement::Production, eventId);
    NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV);

    // Test that offloading events into a smaller buffer with bounded
    // write length results in WEAVE_ERROR_BUFFER_TOO_SMALL and the
    // correct number of events as indicated by eventId

    eventId  = 1;
    eid_prev = eventId;
    testWriter.Init(smallMemoryBackingStore, sizeof(smallMemoryBackingStore));
    err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
        testWriter, nl::Weave::Profiles::DataManagement::Production, eventId);
    NL_TEST_ASSERT(inSuite, err == WEAVE_ERROR_BUFFER_TOO_SMALL);
    {
        TLVReader reader;
        size_t eventCount;
        reader.Init(smallMemoryBackingStore, testWriter.GetLengthWritten());

        err = nl::Weave::TLV::Utilities::Count(reader, eventCount, false);
        NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
        NL_TEST_ASSERT(inSuite, eventId - eid_prev == eventCount);
    }

    // resume event offload; this one should reach the end of the
    // log (by construction)
    testWriter.Init(smallMemoryBackingStore, sizeof(smallMemoryBackingStore));
    err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
        testWriter, nl::Weave::Profiles::DataManagement::Production, eventId);
    NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV);

    // Test that offloading events into a PacketBuffer-backed writer with the default (unbounded) max write length results in
    // WEAVE_ERROR_NO_MEMORY
    eventId = 0;
    testWriter.Init(pbuf);
    err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
        testWriter, nl::Weave::Profiles::DataManagement::Production, eventId);
    NL_TEST_ASSERT(inSuite, err == WEAVE_ERROR_NO_MEMORY);

    PacketBuffer::Free(pbuf);
    pbuf = PacketBuffer::New();
    testWriter.Init(pbuf);
    err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
        testWriter, nl::Weave::Profiles::DataManagement::Production, eventId);
    NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV);

    if (context->bdx)
    {
        DoBDXUpload(context);
    }
}

static void CheckBasicEventDeserialization(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;

    nl::Weave::Profiles::DataManagement::SampleTrait::Event ev, ev2;
    nl::StructureSchemaPointerPair appData;
    nl::Weave::TLV::TLVWriter outer, writer;
    nl::Weave::TLV::TLVReader reader, outerReader;
    uint8_t sBuffer[256];
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;

    InitializeEventLogging(context);

    uint32_t samples[6]    = { 0, 1, 2, 3, 4, 5 };
    ev.state               = 5;
    ev.timestamp           = 328;
    ev.structure.a         = true;
    ev.structure.b.str     = "bloopbloop\0";
    ev.samples.num_samples = 6;
    ev.samples.samples_buf = samples;

    appData.mStructureData = static_cast<void *>(&ev);
    appData.mFieldSchema   = &sampleEventSchema;

    outer.Init(sBuffer, sizeof(sBuffer));

    err = outer.OpenContainer(ProfileTag(0x0A00, 1), kTLVType_Structure, writer);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = SerializedDataToTLVWriterHelper(writer, kTag_EventData, &appData);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = writer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outer.CloseContainer(writer);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    // Verify the encoding

    NL_TEST_ASSERT(inSuite, outer.GetLengthWritten() == sizeof(SampleEventEncoding));
    NL_TEST_ASSERT(inSuite, memcmp(sBuffer, SampleEventEncoding, sizeof(SampleEventEncoding)) == 0);

    // Now de-serialize.

    outerReader.Init(sBuffer, outer.GetLengthWritten());
    err = outerReader.Next(); // Positions us at the beginning of the first element.
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    appData.mStructureData = static_cast<void *>(&ev2);
    appData.mFieldSchema   = &sampleEventSchema;

    err = outerReader.OpenContainer(reader);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = reader.Next(); // Positions us at the beginning of the first element.
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = nl::Weave::Profiles::DataManagement::DeserializeSampleEvent(reader, &ev2, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outerReader.CloseContainer(reader);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, ev2.state == ev.state);
    NL_TEST_ASSERT(inSuite, ev2.timestamp == ev.timestamp);
    NL_TEST_ASSERT(inSuite, ev2.structure.a == ev.structure.a);
    NL_TEST_ASSERT(inSuite, strcmp(ev2.structure.b.str, ev.structure.b.str) == 0);
    NL_TEST_ASSERT(inSuite, ev2.samples.num_samples == ev.samples.num_samples);
    for (uint32_t i = 0; i < ev2.samples.num_samples; i++)
    {
        NL_TEST_ASSERT(inSuite, ev2.samples.samples_buf[i] == ev.samples.samples_buf[i]);
    }

    nl::DeallocateDeserializedStructure(&ev2, &sampleEventSchema, &serializationContext);
}

static void CheckComplexEventDeserialization(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;

    Schema::Nest::Test::Trait::TestETrait::TestEEvent ev  = { 0 };
    Schema::Nest::Test::Trait::TestETrait::TestEEvent ev2 = { 0 };
    nl::StructureSchemaPointerPair appData;
    nl::Weave::TLV::TLVWriter outer, writer;
    nl::Weave::TLV::TLVReader reader, outerReader;
    uint8_t sBuffer[512];
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;

    InitializeEventLogging(context);

    memset(&ev, 0, sizeof(ev));

    uint32_t numbaz[5];
    numbaz[0] = 1;
    numbaz[1] = 3;
    numbaz[2] = 5;
    numbaz[3] = 7;
    numbaz[4] = 10;
    Schema::Nest::Test::Trait::TestCommon::CommonStructE strukchaz[3];
    strukchaz[0].seA = 1111111;
    strukchaz[0].seB = true;
    strukchaz[1].seA = 2222222;
    strukchaz[1].seB = false;
    strukchaz[2].seA = 3333333;
    strukchaz[2].seB = true;
    ev.teA           = 444444;
    ev.teB           = -555555;
    ev.teC           = true;
    ev.teD           = -666666;
    ev.teE.seA       = 777777;
    ev.teE.seB       = false;
    ev.teE.seC       = -888888;
    ev.teF           = 999999;
    ev.teG.seA       = 101010;
    ev.teG.seB       = true;
    ev.teH.num       = sizeof(numbaz) / sizeof(numbaz[0]);
    ev.teH.buf       = numbaz;
    ev.teI.num       = sizeof(strukchaz) / sizeof(strukchaz[0]);
    ev.teI.buf       = strukchaz;
    ev.teJ           = 12121;

    appData.mStructureData = static_cast<void *>(&ev);
    appData.mFieldSchema   = &Schema::Nest::Test::Trait::TestETrait::TestEEvent::FieldSchema;

    outer.Init(sBuffer, sizeof(sBuffer));

    err = outer.OpenContainer(ProfileTag(0x0A00, 1), kTLVType_Structure, writer);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = SerializedDataToTLVWriterHelper(writer, kTag_EventData, &appData);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = writer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outer.CloseContainer(writer);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    // Now de-serialize.

    outerReader.Init(sBuffer, outer.GetLengthWritten());

    err = outerReader.Next(); // Positions us at the beginning of the first element.
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    appData.mStructureData = static_cast<void *>(&ev2);
    appData.mFieldSchema   = &Schema::Nest::Test::Trait::TestETrait::TestEEvent::FieldSchema;

    err = outerReader.OpenContainer(reader);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = reader.Next(); // Positions us at the beginning of the first element.
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = nl::DeserializeEvent(reader, &ev2, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    SuccessOrExit(err);

    err = outerReader.CloseContainer(reader);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, ev2.teA == ev.teA);
    NL_TEST_ASSERT(inSuite, ev2.teB == ev.teB);
    NL_TEST_ASSERT(inSuite, ev2.teC == ev.teC);
    NL_TEST_ASSERT(inSuite, ev2.teD == ev.teD);
    NL_TEST_ASSERT(inSuite, ev2.teE.seA == ev.teE.seA);
    NL_TEST_ASSERT(inSuite, ev2.teE.seB == ev.teE.seB);
    NL_TEST_ASSERT(inSuite, ev2.teE.seC == ev.teE.seC);
    NL_TEST_ASSERT(inSuite, ev2.teF == ev.teF);
    NL_TEST_ASSERT(inSuite, ev2.teG.seA == ev.teG.seA);
    NL_TEST_ASSERT(inSuite, ev2.teG.seB == ev.teG.seB);
    for (uint32_t i = 0; i < ev2.teH.num; i++)
    {
        NL_TEST_ASSERT(inSuite, ev2.teH.buf[i] == ev.teH.buf[i]);
    }
    for (uint32_t i = 0; i < ev2.teI.num; i++)
    {
        NL_TEST_ASSERT(inSuite, ev2.teI.buf[i].seA == ev.teI.buf[i].seA);
        NL_TEST_ASSERT(inSuite, ev2.teI.buf[i].seB == ev.teI.buf[i].seB);
    }
    NL_TEST_ASSERT(inSuite, ev2.IsTeJPresent());
    NL_TEST_ASSERT(inSuite, ev2.teJ == ev.teJ);

    nl::DeallocateEvent(&ev2, &serializationContext);

exit:
    return;
}

static void CheckEmptyArrayEventDeserialization(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;

    nl::Weave::Profiles::DataManagement::SampleTrait::Event ev, ev2;
    nl::StructureSchemaPointerPair appData;
    nl::Weave::TLV::TLVWriter outer, writer;
    nl::Weave::TLV::TLVReader reader, outerReader;
    uint8_t sBuffer[256];
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;

    InitializeEventLogging(context);

    ev.state               = 5;
    ev.timestamp           = 328;
    ev.structure.a         = true;
    ev.structure.b.str     = "bloopbloop\0";
    ev.samples.num_samples = 0;
    ev.samples.samples_buf = NULL;

    appData.mStructureData = static_cast<void *>(&ev);
    appData.mFieldSchema   = &sampleEventSchema;

    outer.Init(sBuffer, sizeof(sBuffer));

    err = outer.OpenContainer(ProfileTag(0x0A00, 1), kTLVType_Structure, writer);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = SerializedDataToTLVWriterHelper(writer, kTag_EventData, &appData);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = writer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outer.CloseContainer(writer);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outer.Finalize();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    // Verify the encoding

    NL_TEST_ASSERT(inSuite, outer.GetLengthWritten() == sizeof(SampleEmptyArrayEventEncoding));
    NL_TEST_ASSERT(inSuite, memcmp(sBuffer, SampleEmptyArrayEventEncoding, sizeof(SampleEmptyArrayEventEncoding)) == 0);

    // Now de-serialize.

    outerReader.Init(sBuffer, outer.GetLengthWritten());

    err = outerReader.Next(); // Positions us at the beginning of the first element.
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    appData.mStructureData = static_cast<void *>(&ev2);
    appData.mFieldSchema   = &sampleEventSchema;

    err = outerReader.OpenContainer(reader);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = reader.Next(); // Positions us at the beginning of the first element.
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = nl::Weave::Profiles::DataManagement::DeserializeSampleEvent(reader, &ev2, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = outerReader.CloseContainer(reader);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, ev2.state == ev.state);
    NL_TEST_ASSERT(inSuite, ev2.timestamp == ev.timestamp);
    NL_TEST_ASSERT(inSuite, ev2.structure.a == ev.structure.a);
    NL_TEST_ASSERT(inSuite, strcmp(ev2.structure.b.str, ev.structure.b.str) == 0);
    NL_TEST_ASSERT(inSuite, ev2.samples.num_samples == ev.samples.num_samples);
    NL_TEST_ASSERT(inSuite, ev2.samples.samples_buf == NULL);

    memMgmt.mem_free((void *) ev2.structure.b.str);
}

static WEAVE_ERROR FetchEventsHelper(TLVReader & aReader, event_id_t aEventId, uint8_t * aBackingStore, size_t aLen,
                                     ImportanceType aImportance)
{
    WEAVE_ERROR err;
    TLVWriter testWriter;
    TLVType readerType;

    testWriter.Init(aBackingStore, aLen);
    err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(testWriter, aImportance, aEventId);
    VerifyOrExit(err == WEAVE_END_OF_TLV, err = WEAVE_ERROR_INCORRECT_STATE);

    aReader.Init(aBackingStore, testWriter.GetLengthWritten());

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

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

    while ((aReader.GetTag() != ContextTag(kTag_EventData)) && (err == WEAVE_NO_ERROR))
    {
        err = aReader.Next();
    }

exit:
    return err;
}

class TestEventProcessor : public EventProcessor
{
public:
    TestEventProcessor();
    WEAVE_ERROR ProcessEvent(TLVReader inReader, SubscriptionClient & inClient, const EventHeader & inEventHeader);
    WEAVE_ERROR GapDetected(const EventHeader & inEventHeader);

    SchemaVersionRange mSchemaVersionRange;
};

TestEventProcessor::TestEventProcessor() : EventProcessor(0) { }

WEAVE_ERROR TestEventProcessor::ProcessEvent(TLVReader inReader, SubscriptionClient & inClient, const EventHeader & inEventHeader)
{
    mSchemaVersionRange = inEventHeader.mDataSchemaVersionRange;
    return WEAVE_NO_ERROR;
}

WEAVE_ERROR TestEventProcessor::GapDetected(const EventHeader & inEventHeader)
{
    return WEAVE_NO_ERROR;
}

static WEAVE_ERROR VersionCompatibilityHelper(void * inContext, SchemaVersionRange & encodedSchemaVersionRange,
                                              SchemaVersionRange & decodedSchemaVersionRange)
{
    WEAVE_ERROR err;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLoggingWithPersistedCounters(context, 1, nl::Weave::Profiles::DataManagement::Production);

    TLVReader testReader;
    uint8_t backingStore[1024];
    uint32_t bytesWritten;
    Schema::Nest::Test::Trait::TestETrait::TestEEvent evN = { 0 };
    EventSchema testSchema                                = Schema::Nest::Test::Trait::TestETrait::TestEEvent::Schema;
    TestEventProcessor eventProcessor;

    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;
    nl::StructureSchemaPointerPair appData;

    PrepareBinding(context);
    InitSubscriptionClient(context);

    testSchema.mMinCompatibleDataSchemaVersion = encodedSchemaVersionRange.mMinVersion;
    testSchema.mDataSchemaVersion              = encodedSchemaVersionRange.mMaxVersion;

    appData.mStructureData = static_cast<void *>(&evN);
    appData.mFieldSchema   = &Schema::Nest::Test::Trait::TestETrait::TestEEvent::FieldSchema;

    event_id_t eventId =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);

    err = FetchEventsHelper(testReader, eventId, backingStore, sizeof(backingStore));
    SuccessOrExit(err);

    bytesWritten = testReader.GetRemainingLength() + testReader.GetLengthRead();
    testReader.Init(backingStore, bytesWritten);

    err = eventProcessor.ProcessEvents(testReader, *context->mSubClient);
    SuccessOrExit(err);

    decodedSchemaVersionRange = eventProcessor.mSchemaVersionRange;

    if (context->mVerbose)
    {
        nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
    }

exit:
    return err;
}

static void CheckVersion1DataCompatibility(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err;
    SchemaVersionRange encodedSchemaVersionRange, decodedSchemaVersionRange;

    encodedSchemaVersionRange.mMaxVersion = 1;
    encodedSchemaVersionRange.mMinVersion = 1;

    err = VersionCompatibilityHelper(inContext, encodedSchemaVersionRange, decodedSchemaVersionRange);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, encodedSchemaVersionRange == decodedSchemaVersionRange);
}

static void CheckForwardDataCompatibility(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err;
    SchemaVersionRange encodedSchemaVersionRange, decodedSchemaVersionRange;

    encodedSchemaVersionRange.mMaxVersion = 4;
    encodedSchemaVersionRange.mMinVersion = 1;

    err = VersionCompatibilityHelper(inContext, encodedSchemaVersionRange, decodedSchemaVersionRange);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, encodedSchemaVersionRange == decodedSchemaVersionRange);
}

static void CheckDataIncompatibility(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err;
    SchemaVersionRange encodedSchemaVersionRange, decodedSchemaVersionRange;

    encodedSchemaVersionRange.mMaxVersion = 4;
    encodedSchemaVersionRange.mMinVersion = 2;

    err = VersionCompatibilityHelper(inContext, encodedSchemaVersionRange, decodedSchemaVersionRange);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, encodedSchemaVersionRange == decodedSchemaVersionRange);
}

namespace {

class FakeEventProcessor : public EventProcessor
{
public:
    FakeEventProcessor();
    void ClearMock();
    WEAVE_ERROR ProcessEvent(TLVReader inReader, SubscriptionClient & inClient, const EventHeader & inEventHeader);
    WEAVE_ERROR GapDetected(const EventHeader & inEventHeader);

    EventHeader mLastEventHeader;
    bool mGapDetected;
    EventHeader mGapEventHeader;
    int mEventsProcessed;
};

FakeEventProcessor::FakeEventProcessor() :
    EventProcessor(0), mLastEventHeader(), mGapDetected(false), mGapEventHeader(), mEventsProcessed()
{ }

void FakeEventProcessor::ClearMock()
{
    mLastEventHeader = EventHeader();
    mGapDetected     = false;
    mGapEventHeader  = EventHeader();
    mEventsProcessed = 0;
}

WEAVE_ERROR FakeEventProcessor::ProcessEvent(TLVReader inReader, SubscriptionClient & inClient, const EventHeader & inEventHeader)
{
    mLastEventHeader = inEventHeader;
    mEventsProcessed++;
    return WEAVE_NO_ERROR;
}

WEAVE_ERROR FakeEventProcessor::GapDetected(const EventHeader & inEventHeader)
{
    mGapDetected    = true;
    mGapEventHeader = inEventHeader;
    return WEAVE_NO_ERROR;
}

} // namespace

static void CheckGapDetection(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLoggingWithPersistedCounters(context, 1, nl::Weave::Profiles::DataManagement::Production);

    TLVReader testReader;
    uint8_t backingStore[1024];
    uint32_t bytesWritten;
    Schema::Nest::Test::Trait::TestETrait::TestEEvent evN = { 0 };
    EventSchema testSchema                                = Schema::Nest::Test::Trait::TestETrait::TestEEvent::Schema;
    FakeEventProcessor eventProcessor;

    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;
    nl::StructureSchemaPointerPair appData;

    PrepareBinding(context);
    InitSubscriptionClient(context);

    appData.mStructureData = static_cast<void *>(&evN);
    appData.mFieldSchema   = &Schema::Nest::Test::Trait::TestETrait::TestEEvent::FieldSchema;

    // Arrange two consecutive events
    event_id_t eventId_A =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);
    event_id_t eventId_B =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);

    IgnoreUnusedVariable(eventId_B);

    // Arrange testReader with all events from the start
    err = FetchEventsHelper(testReader, eventId_A, backingStore, sizeof(backingStore));
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    bytesWritten = testReader.GetRemainingLength() + testReader.GetLengthRead();
    testReader.Init(backingStore, bytesWritten);
    err = eventProcessor.ProcessEvents(testReader, *context->mSubClient);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, eventProcessor.mGapDetected == false);
    NL_TEST_ASSERT(inSuite, eventProcessor.mEventsProcessed == 2);

    eventProcessor.ClearMock();

    // Arrange two more consecutive events
    event_id_t eventId_C =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);
    event_id_t eventId_D =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);

    IgnoreUnusedVariable(eventId_C);

    // Arrange testReader skipping eventId_C
    err = FetchEventsHelper(testReader, eventId_D, backingStore, sizeof(backingStore));
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    bytesWritten = testReader.GetRemainingLength() + testReader.GetLengthRead();
    testReader.Init(backingStore, bytesWritten);
    err = eventProcessor.ProcessEvents(testReader, *context->mSubClient);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, eventProcessor.mGapDetected == true);
    NL_TEST_ASSERT(inSuite, eventProcessor.mEventsProcessed == 1);

    eventProcessor.ClearMock();
}

static void CheckDropOverlap(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLoggingWithPersistedCounters(context, 1, nl::Weave::Profiles::DataManagement::Production);

    TLVReader testReader;
    uint8_t backingStore[1024];
    uint32_t bytesWritten;
    Schema::Nest::Test::Trait::TestETrait::TestEEvent evN = { 0 };
    EventSchema testSchema                                = Schema::Nest::Test::Trait::TestETrait::TestEEvent::Schema;
    FakeEventProcessor eventProcessor;

    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;
    nl::StructureSchemaPointerPair appData;

    PrepareBinding(context);
    InitSubscriptionClient(context);

    appData.mStructureData = static_cast<void *>(&evN);
    appData.mFieldSchema   = &Schema::Nest::Test::Trait::TestETrait::TestEEvent::FieldSchema;

    // Arrange two consecutive events
    event_id_t eventId_A =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);
    event_id_t eventId_B =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);

    // Arrange testReader with all events from the start
    err = FetchEventsHelper(testReader, eventId_A, backingStore, sizeof(backingStore));
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    bytesWritten = testReader.GetRemainingLength() + testReader.GetLengthRead();
    testReader.Init(backingStore, bytesWritten);

    err = eventProcessor.ProcessEvents(testReader, *context->mSubClient);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, eventProcessor.mGapDetected == false);
    NL_TEST_ASSERT(inSuite, eventProcessor.mEventsProcessed == 2);

    eventProcessor.ClearMock();

    // Arrange two more consecutive events
    event_id_t eventId_C =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);
    event_id_t eventId_D =
        nl::Weave::Profiles::DataManagement::LogEvent(testSchema, nl::SerializedDataToTLVWriterHelper, (void *) &appData);

    IgnoreUnusedVariable(eventId_C);
    IgnoreUnusedVariable(eventId_D);

    // Arrange testReader overlapping eventId_B
    err = FetchEventsHelper(testReader, eventId_B, backingStore, sizeof(backingStore));
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    bytesWritten = testReader.GetRemainingLength() + testReader.GetLengthRead();
    testReader.Init(backingStore, bytesWritten);

    err = eventProcessor.ProcessEvents(testReader, *context->mSubClient);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, eventProcessor.mGapDetected == false);
    NL_TEST_ASSERT(inSuite, eventProcessor.mEventsProcessed == 2);

    eventProcessor.ClearMock();

    // Arrange testReader overlapping all events
    err = FetchEventsHelper(testReader, eventId_A, backingStore, sizeof(backingStore));
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    bytesWritten = testReader.GetRemainingLength() + testReader.GetLengthRead();
    testReader.Init(backingStore, bytesWritten);

    err = eventProcessor.ProcessEvents(testReader, *context->mSubClient);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, eventProcessor.mGapDetected == false);
    NL_TEST_ASSERT(inSuite, eventProcessor.mEventsProcessed == 0);

    eventProcessor.ClearMock();
}

static void CheckNullableFieldsSimple(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;

    TLVReader testReader;
    uint8_t backingStore[1024];
    Schema::Nest::Test::Trait::TestETrait::TestEEvent evN             = { 0 };
    Schema::Nest::Test::Trait::TestETrait::TestEEvent deserializedEvN = { 0 };

    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;

    InitializeEventLogging(context);

    evN.teA = 10;
    evN.SetTeJNull();

    event_id_t eventId = nl::LogEvent(&evN);

    err = FetchEventsHelper(testReader, eventId, backingStore, sizeof(backingStore));
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    if (context->mVerbose)
    {
        nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
    }

    err = nl::DeserializeEvent(testReader, &deserializedEvN, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, deserializedEvN.teA == evN.teA);
    NL_TEST_ASSERT(inSuite, GET_FIELD_NULLIFIED_BIT(deserializedEvN.__nullified_fields__, 0));
    NL_TEST_ASSERT(inSuite, deserializedEvN.IsTeJPresent() == false);
}

static void CheckNullableFieldsComplex(nlTestSuite * inSuite, void * inContext)
{
    // pattern: for each bit in nullified fields, set and check
    // for array of nullable structs, set and check
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;

    uint8_t backingStore[1024];
    Schema::Nest::Test::Trait::TestETrait::TestENullableEvent teN_s = { 0 };

    teN_s.neA     = 0xAAAAAAAA;
    teN_s.neB     = -1;
    teN_s.neC     = true;
    teN_s.neD     = "bar\0";
    teN_s.neE     = 5;
    teN_s.neF     = 0x77777777;
    teN_s.neG     = -30;
    teN_s.neH     = false;
    teN_s.neI     = "foo\0";
    teN_s.neJ.neA = 88;
    teN_s.neJ.neB = true;

    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;

    InitializeEventLogging(context);

    // hardcoded number nullable fields
    for (int i = 0; i < 10; i++)
    {
        Schema::Nest::Test::Trait::TestETrait::TestENullableEvent teN_d = { 0 };
        event_id_t eventId;
        TLVReader testReader;

        memset(teN_s.__nullified_fields__, 0, sizeof(teN_s.__nullified_fields__));
        memset(teN_s.neJ.__nullified_fields__, 0, sizeof(teN_s.neJ.__nullified_fields__));
        SET_FIELD_NULLIFIED_BIT(teN_s.__nullified_fields__, i);

        eventId = nl::LogEvent(&teN_s);

        err = FetchEventsHelper(testReader, eventId, backingStore, sizeof(backingStore));
        NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

        err = nl::DeserializeEvent(testReader, &teN_d, &serializationContext);
        NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

        NL_TEST_ASSERT(inSuite, GET_FIELD_NULLIFIED_BIT(teN_d.__nullified_fields__, i));

        if (i != 0)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neA == teN_s.neA);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeAPresent() == false);
        }

        if (i != 1)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neB == teN_s.neB);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeBPresent() == false);
        }

        if (i != 2)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neC == teN_s.neC);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeCPresent() == false);
        }

        if (i != 3)
        {
            NL_TEST_ASSERT(inSuite, strcmp(teN_d.neD, teN_s.neD) == 0);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeDPresent() == false);
        }

        if (i != 4)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neE == teN_s.neE);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeEPresent() == false);
        }

        if (i != 5)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neF == teN_s.neF);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeFPresent() == false);
        }

        if (i != 6)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neG == teN_s.neG);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeGPresent() == false);
        }

        if (i != 7)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neH == teN_s.neH);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeHPresent() == false);
        }

        if (i != 8)
        {
            NL_TEST_ASSERT(inSuite, strcmp(teN_d.neI, teN_s.neI) == 0);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeIPresent() == false);
        }

        if (i != 9)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neJ.neA == teN_s.neJ.neA);
            NL_TEST_ASSERT(inSuite, teN_d.neJ.neB == teN_s.neJ.neB);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.IsNeJPresent() == false);
        }

        err = nl::DeallocateEvent(&teN_d, &serializationContext);
        NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    }

    for (int i = 0; i < 2; i++)
    {
        Schema::Nest::Test::Trait::TestETrait::TestENullableEvent teN_d = { 0 };
        event_id_t eventId;
        TLVReader testReader;

        memset(teN_s.__nullified_fields__, 0, sizeof(teN_s.__nullified_fields__));
        memset(teN_s.neJ.__nullified_fields__, 0, sizeof(teN_s.neJ.__nullified_fields__));
        SET_FIELD_NULLIFIED_BIT(teN_s.neJ.__nullified_fields__, i);

        eventId = nl::LogEvent(&teN_s);

        err = FetchEventsHelper(testReader, eventId, backingStore, sizeof(backingStore));
        NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

        err = nl::DeserializeEvent(testReader, &teN_d, &serializationContext);
        NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

        NL_TEST_ASSERT(inSuite, GET_FIELD_NULLIFIED_BIT(teN_d.neJ.__nullified_fields__, i));

        NL_TEST_ASSERT(inSuite, teN_d.neA == teN_s.neA);
        NL_TEST_ASSERT(inSuite, teN_d.neB == teN_s.neB);
        NL_TEST_ASSERT(inSuite, teN_d.neC == teN_s.neC);
        NL_TEST_ASSERT(inSuite, strcmp(teN_d.neD, teN_s.neD) == 0);
        NL_TEST_ASSERT(inSuite, teN_d.neE == teN_s.neE);
        NL_TEST_ASSERT(inSuite, teN_d.neF == teN_s.neF);
        NL_TEST_ASSERT(inSuite, teN_d.neG == teN_s.neG);
        NL_TEST_ASSERT(inSuite, teN_d.neH == teN_s.neH);
        NL_TEST_ASSERT(inSuite, strcmp(teN_d.neI, teN_s.neI) == 0);

        if (i == 1)
        {
            NL_TEST_ASSERT(inSuite, teN_d.neJ.neA == teN_s.neJ.neA);
            NL_TEST_ASSERT(inSuite, teN_d.neJ.IsNeBPresent() == false);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, teN_d.neJ.neB == teN_s.neJ.neB);
            NL_TEST_ASSERT(inSuite, teN_d.neJ.IsNeAPresent() == false);
        }
    }
}

static void CheckWDMOffloadTrigger(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    timestamp_t now;
    size_t counter = 0;
    uint32_t eventSize;
    ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler * testSubHandler;
    ::nl::Weave::Profiles::DataManagement::SubscriptionHandler * subHandler;
    nl::Weave::Profiles::DataManagement::LoggingManagement & logger =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    event_id_t eid, eid_prev;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLogging(context);

    // Each event is about 40 bytes; write 40 of those to ensure we
    // override the default WDM event byte threshold

    now       = System::Layer::GetClock_MonotonicMS();
    eid_prev  = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter++);
    eventSize = logger.GetBytesWritten();

    for (size_t expectedBufferSize = 0; expectedBufferSize < WEAVE_CONFIG_EVENT_LOGGING_BYTE_THRESHOLD;
         expectedBufferSize += eventSize)
    {
        now += 10;
        eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter++);
        NL_TEST_ASSERT(inSuite, eid == (eid_prev + 1));
        eid_prev = eid;
    }

    // subscription engine has no subscription handlers, we should not be running the WDM
    NL_TEST_ASSERT(inSuite, logger.CheckShouldRunWDM() == false);

    // create a fake subscription, and start messing with it to check that WDM trigger will run
    err = ::nl::Weave::Profiles::DataManagement::SubscriptionEngine::GetInstance()->NewSubscriptionHandler(&subHandler);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    testSubHandler = static_cast<::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler *>(subHandler);
    new (testSubHandler)::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler();

    NL_TEST_ASSERT(inSuite, testSubHandler->IsFree());

    NL_TEST_ASSERT(inSuite, logger.CheckShouldRunWDM() == false);

    testSubHandler->SetActive();
    NL_TEST_ASSERT(inSuite, logger.CheckShouldRunWDM() == true);

    testSubHandler->SetEventLogEndpoint(logger);
    NL_TEST_ASSERT(inSuite, logger.CheckShouldRunWDM() == false);

    // A single event at this point should not trigger the engine
    eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter++);
    NL_TEST_ASSERT(inSuite, eid == (eid_prev + 1));
    NL_TEST_ASSERT(inSuite, logger.CheckShouldRunWDM() == false);
}

// Mock'd Events (would be autogen'd by phoenix)
struct CurrentEvent
{
    int32_t enumState;
    bool boolState;
    static const nl::SchemaFieldDescriptor FieldSchema;
    enum
    {
        kProfileId   = 0x1U,
        kEventTypeId = 0x1U
    };
    static const nl::Weave::Profiles::DataManagement::EventSchema Schema;
};
const nl::FieldDescriptor CurrentEventFieldDescriptors[] = {
    { NULL, offsetof(CurrentEvent, enumState), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 0), 1 },
    { NULL, offsetof(CurrentEvent, boolState), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeBoolean, 0), 32 },
};
const nl::SchemaFieldDescriptor CurrentEvent::FieldSchema = { .mNumFieldDescriptorElements = sizeof(CurrentEventFieldDescriptors) /
                                                                  sizeof(CurrentEventFieldDescriptors[0]),
                                                              .mFields = CurrentEventFieldDescriptors,
                                                              .mSize   = sizeof(CurrentEvent) };
const nl::Weave::Profiles::DataManagement::EventSchema CurrentEvent::Schema = {
    .mProfileId                      = kProfileId,
    .mStructureType                  = 0x1,
    .mImportance                     = nl::Weave::Profiles::DataManagement::ProductionCritical,
    .mDataSchemaVersion              = 1,
    .mMinCompatibleDataSchemaVersion = 1
};

struct FutureEventNewBaseField
{
    int32_t enumState;
    int32_t otherEnumState;
    bool boolState;
    static const nl::SchemaFieldDescriptor FieldSchema;
    enum
    {
        kProfileId   = 0x1U,
        kEventTypeId = 0x1U
    };
    static const nl::Weave::Profiles::DataManagement::EventSchema Schema;
};
const nl::FieldDescriptor FutureEventNewBaseFieldFieldDescriptors[] = {
    { NULL, offsetof(FutureEventNewBaseField, enumState), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 0), 1 },
    { NULL, offsetof(FutureEventNewBaseField, otherEnumState), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 0), 2 },
    { NULL, offsetof(FutureEventNewBaseField, boolState), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeBoolean, 0), 32 },
};
const nl::SchemaFieldDescriptor FutureEventNewBaseField::FieldSchema                   = { .mNumFieldDescriptorElements =
                                                                             sizeof(FutureEventNewBaseFieldFieldDescriptors) /
                                                                             sizeof(FutureEventNewBaseFieldFieldDescriptors[0]),
                                                                         .mFields = FutureEventNewBaseFieldFieldDescriptors,
                                                                         .mSize   = sizeof(FutureEventNewBaseField) };
const nl::Weave::Profiles::DataManagement::EventSchema FutureEventNewBaseField::Schema = {
    .mProfileId                      = kProfileId,
    .mStructureType                  = 0x1,
    .mImportance                     = nl::Weave::Profiles::DataManagement::ProductionCritical,
    .mDataSchemaVersion              = 2,
    .mMinCompatibleDataSchemaVersion = 1
};

static void CheckDeserializingNewerVersion(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;
    uint8_t backingStore[1024];
    InitializeEventLogging(context);

    FutureEventNewBaseField externalEv = { 0 };
    externalEv.enumState               = 10;
    externalEv.otherEnumState          = 20;
    externalEv.boolState               = true;

    event_id_t eventId = nl::LogEvent(&externalEv);

    TLVReader testReader;
    err = FetchEventsHelper(testReader, eventId, backingStore, sizeof(backingStore),
                            nl::Weave::Profiles::DataManagement::ProductionCritical);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    if (context->mVerbose)
    {
        nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
    }

    CurrentEvent deserializedEv = { 0 };
    nl::StructureSchemaPointerPair structureSchemaPair;
    structureSchemaPair.mStructureData = &deserializedEv;
    structureSchemaPair.mFieldSchema   = &CurrentEvent::FieldSchema;

    err = nl::TLVReaderToDeserializedDataHelper(testReader, nl::Weave::Profiles::DataManagement::kTag_EventData,
                                                (void *) &structureSchemaPair, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, deserializedEv.enumState == externalEv.enumState);
    NL_TEST_ASSERT(inSuite, deserializedEv.boolState == externalEv.boolState);
}

static void CheckDeserializingOlderVersion(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;
    uint8_t backingStore[1024];
    InitializeEventLogging(context);

    CurrentEvent externalEv = { 0 };
    externalEv.enumState    = 10;
    externalEv.boolState    = true;

    event_id_t eventId = nl::LogEvent(&externalEv);

    TLVReader testReader;
    err = FetchEventsHelper(testReader, eventId, backingStore, sizeof(backingStore),
                            nl::Weave::Profiles::DataManagement::ProductionCritical);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    if (context->mVerbose)
    {
        nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
    }

    FutureEventNewBaseField deserializedEv = { 0 };
    nl::StructureSchemaPointerPair structureSchemaPair;
    structureSchemaPair.mStructureData = &deserializedEv;
    structureSchemaPair.mFieldSchema   = &FutureEventNewBaseField::FieldSchema;

    err = nl::TLVReaderToDeserializedDataHelper(testReader, nl::Weave::Profiles::DataManagement::kTag_EventData,
                                                (void *) &structureSchemaPair, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, deserializedEv.enumState == externalEv.enumState);
    NL_TEST_ASSERT(inSuite, deserializedEv.otherEnumState == 0);
    NL_TEST_ASSERT(inSuite, deserializedEv.boolState == externalEv.boolState);
}

// ---------------
struct CurrentNullableEvent
{
    int32_t baseEnum;
    void SetBaseEnumNull(void);
    void SetBaseEnumPresent(void);
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
    bool IsBaseEnumPresent(void);
#endif

    int32_t extendedEnum;
    void SetExtendedEnumNull(void);
    void SetExtendedEnumPresent(void);
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
    bool IsExtendedEnumPresent(void);
#endif
    uint8_t __nullified_fields__[2 / 8 + 1];
    static const nl::SchemaFieldDescriptor FieldSchema;
    enum
    {
        kProfileId   = 0x1U,
        kEventTypeId = 0x1U
    };
    static const nl::Weave::Profiles::DataManagement::EventSchema Schema;
};
const nl::FieldDescriptor CurrentNullableEventFieldDescriptors[] = {
    { NULL, offsetof(CurrentNullableEvent, baseEnum), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 1), 1 },
    { NULL, offsetof(CurrentNullableEvent, extendedEnum), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 1), 32 },
};
const nl::SchemaFieldDescriptor CurrentNullableEvent::FieldSchema = {
    .mNumFieldDescriptorElements = sizeof(CurrentNullableEventFieldDescriptors) / sizeof(CurrentNullableEventFieldDescriptors[0]),
    .mFields                     = CurrentNullableEventFieldDescriptors,
    .mSize                       = sizeof(CurrentNullableEvent)
};
const nl::Weave::Profiles::DataManagement::EventSchema CurrentNullableEvent::Schema = {
    .mProfileId                      = kProfileId,
    .mStructureType                  = 0x1,
    .mImportance                     = nl::Weave::Profiles::DataManagement::ProductionCritical,
    .mDataSchemaVersion              = 2,
    .mMinCompatibleDataSchemaVersion = 1
};
inline void CurrentNullableEvent::SetBaseEnumNull(void)
{
    SET_FIELD_NULLIFIED_BIT(__nullified_fields__, 0);
}
inline void CurrentNullableEvent::SetBaseEnumPresent(void)
{
    CLEAR_FIELD_NULLIFIED_BIT(__nullified_fields__, 0);
}
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
inline bool CurrentNullableEvent::IsBaseEnumPresent(void)
{
    return (!GET_FIELD_NULLIFIED_BIT(__nullified_fields__, 0));
}
#endif
inline void CurrentNullableEvent::SetExtendedEnumNull(void)
{
    SET_FIELD_NULLIFIED_BIT(__nullified_fields__, 1);
}
inline void CurrentNullableEvent::SetExtendedEnumPresent(void)
{
    CLEAR_FIELD_NULLIFIED_BIT(__nullified_fields__, 1);
}
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
inline bool CurrentNullableEvent::IsExtendedEnumPresent(void)
{
    return (!GET_FIELD_NULLIFIED_BIT(__nullified_fields__, 1));
}
#endif

struct FutureNullableEvent
{
    int32_t baseEnum;
    void SetBaseEnumNull(void);
    void SetBaseEnumPresent(void);
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
    bool IsBaseEnumPresent(void);
#endif

    int32_t futureEnum;
    void SetFutureEnumNull(void);
    void SetFutureEnumPresent(void);
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
    bool IsFutureEnumPresent(void);
#endif

    int32_t extendedEnum;
    void SetExtendedEnumNull(void);
    void SetExtendedEnumPresent(void);
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
    bool IsExtendedEnumPresent(void);
#endif

    int32_t futureExtendedEnum;
    void SetFutureExtendedEnumNull(void);
    void SetFutureExtendedEnumPresent(void);
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
    bool IsFutureExtendedEnumPresent(void);
#endif

    uint8_t __nullified_fields__[4 / 8 + 1];
    static const nl::SchemaFieldDescriptor FieldSchema;
    enum
    {
        kProfileId   = 0x1U,
        kEventTypeId = 0x1U
    };
    static const nl::Weave::Profiles::DataManagement::EventSchema Schema;
};
const nl::FieldDescriptor FutureNullableEventFieldDescriptors[] = {
    { NULL, offsetof(FutureNullableEvent, baseEnum), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 1), 1 },
    { NULL, offsetof(FutureNullableEvent, futureEnum), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 1), 2 },
    { NULL, offsetof(FutureNullableEvent, extendedEnum), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 1), 32 },
    { NULL, offsetof(FutureNullableEvent, futureExtendedEnum), SET_TYPE_AND_FLAGS(nl::SerializedFieldTypeInt32, 1), 33 },
};
const nl::SchemaFieldDescriptor FutureNullableEvent::FieldSchema = {
    .mNumFieldDescriptorElements = sizeof(FutureNullableEventFieldDescriptors) / sizeof(FutureNullableEventFieldDescriptors[0]),
    .mFields                     = FutureNullableEventFieldDescriptors,
    .mSize                       = sizeof(FutureNullableEvent)
};
const nl::Weave::Profiles::DataManagement::EventSchema FutureNullableEvent::Schema = {
    .mProfileId                      = kProfileId,
    .mStructureType                  = 0x1,
    .mImportance                     = nl::Weave::Profiles::DataManagement::ProductionCritical,
    .mDataSchemaVersion              = 2,
    .mMinCompatibleDataSchemaVersion = 1
};
inline void FutureNullableEvent::SetBaseEnumNull(void)
{
    SET_FIELD_NULLIFIED_BIT(__nullified_fields__, 0);
}
inline void FutureNullableEvent::SetBaseEnumPresent(void)
{
    CLEAR_FIELD_NULLIFIED_BIT(__nullified_fields__, 0);
}
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
inline bool FutureNullableEvent::IsBaseEnumPresent(void)
{
    return (!GET_FIELD_NULLIFIED_BIT(__nullified_fields__, 0));
}
#endif
inline void FutureNullableEvent::SetFutureEnumNull(void)
{
    SET_FIELD_NULLIFIED_BIT(__nullified_fields__, 1);
}
inline void FutureNullableEvent::SetFutureEnumPresent(void)
{
    CLEAR_FIELD_NULLIFIED_BIT(__nullified_fields__, 1);
}
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
inline bool FutureNullableEvent::IsFutureEnumPresent(void)
{
    return (!GET_FIELD_NULLIFIED_BIT(__nullified_fields__, 1));
}
#endif
inline void FutureNullableEvent::SetExtendedEnumNull(void)
{
    SET_FIELD_NULLIFIED_BIT(__nullified_fields__, 2);
}
inline void FutureNullableEvent::SetExtendedEnumPresent(void)
{
    CLEAR_FIELD_NULLIFIED_BIT(__nullified_fields__, 2);
}
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
inline bool FutureNullableEvent::IsExtendedEnumPresent(void)
{
    return (!GET_FIELD_NULLIFIED_BIT(__nullified_fields__, 2));
}
#endif
inline void FutureNullableEvent::SetFutureExtendedEnumNull(void)
{
    SET_FIELD_NULLIFIED_BIT(__nullified_fields__, 3);
}
inline void FutureNullableEvent::SetFutureExtendedEnumPresent(void)
{
    CLEAR_FIELD_NULLIFIED_BIT(__nullified_fields__, 3);
}
#if WEAVE_CONFIG_SERIALIZATION_ENABLE_DESERIALIZATION
inline bool FutureNullableEvent::IsFutureExtendedEnumPresent(void)
{
    return (!GET_FIELD_NULLIFIED_BIT(__nullified_fields__, 3));
}
#endif

static void CheckDeserializingNewerVersionNullable(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;
    uint8_t backingStore[1024];
    InitializeEventLogging(context);

    FutureNullableEvent externalEv = { 0 };
    externalEv.baseEnum            = 50;
    externalEv.SetBaseEnumPresent();
    externalEv.SetFutureEnumNull();
    externalEv.extendedEnum = 70;
    externalEv.SetExtendedEnumPresent();
    externalEv.SetFutureExtendedEnumNull();

    event_id_t eventId = nl::LogEvent(&externalEv);

    TLVReader testReader;
    err = FetchEventsHelper(testReader, eventId, backingStore, sizeof(backingStore),
                            nl::Weave::Profiles::DataManagement::ProductionCritical);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    if (context->mVerbose)
    {
        nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
    }

    CurrentNullableEvent deserializedEv = { 0 };
    nl::StructureSchemaPointerPair structureSchemaPair;
    structureSchemaPair.mStructureData = &deserializedEv;
    structureSchemaPair.mFieldSchema   = &CurrentNullableEvent::FieldSchema;

    err = nl::TLVReaderToDeserializedDataHelper(testReader, nl::Weave::Profiles::DataManagement::kTag_EventData,
                                                (void *) &structureSchemaPair, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, deserializedEv.IsBaseEnumPresent());
    NL_TEST_ASSERT(inSuite, deserializedEv.IsBaseEnumPresent() == externalEv.IsBaseEnumPresent());
    NL_TEST_ASSERT(inSuite, deserializedEv.baseEnum == externalEv.baseEnum);

    NL_TEST_ASSERT(inSuite, deserializedEv.IsExtendedEnumPresent());
    NL_TEST_ASSERT(inSuite, deserializedEv.IsExtendedEnumPresent() == externalEv.IsExtendedEnumPresent());
    NL_TEST_ASSERT(inSuite, deserializedEv.extendedEnum == externalEv.extendedEnum);
}

static void CheckDeserializingOlderVersionNullable(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    WEAVE_ERROR err;
    nl::MemoryManagement memMgmt = { malloc, free, realloc };
    nl::SerializationContext serializationContext;
    serializationContext.memMgmt = memMgmt;
    uint8_t backingStore[1024];
    InitializeEventLogging(context);

    CurrentNullableEvent externalEv = { 0 };
    externalEv.baseEnum             = 50;
    externalEv.SetBaseEnumPresent();
    externalEv.SetExtendedEnumNull();

    event_id_t eventId = nl::LogEvent(&externalEv);

    TLVReader testReader;
    err = FetchEventsHelper(testReader, eventId, backingStore, sizeof(backingStore),
                            nl::Weave::Profiles::DataManagement::ProductionCritical);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    if (context->mVerbose)
    {
        nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
    }

    FutureNullableEvent deserializedEv = { 0 };
    nl::StructureSchemaPointerPair structureSchemaPair;
    structureSchemaPair.mStructureData = &deserializedEv;
    structureSchemaPair.mFieldSchema   = &FutureNullableEvent::FieldSchema;

    err = nl::TLVReaderToDeserializedDataHelper(testReader, nl::Weave::Profiles::DataManagement::kTag_EventData,
                                                (void *) &structureSchemaPair, &serializationContext);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    NL_TEST_ASSERT(inSuite, deserializedEv.IsBaseEnumPresent());
    NL_TEST_ASSERT(inSuite, deserializedEv.IsBaseEnumPresent() == externalEv.IsBaseEnumPresent());
    NL_TEST_ASSERT(inSuite, deserializedEv.baseEnum == externalEv.baseEnum);

    NL_TEST_ASSERT(inSuite, deserializedEv.IsFutureEnumPresent() == false);
    NL_TEST_ASSERT(inSuite, deserializedEv.IsExtendedEnumPresent() == false);
    NL_TEST_ASSERT(inSuite, deserializedEv.IsFutureExtendedEnumPresent() == false);
}

static void CheckSubscriptionHandlerHelper(nlTestSuite * inSuite, TestLoggingContext * context, bool inLogInfoEvents)
{
    WEAVE_ERROR err;
    timestamp_t now;
    size_t counter = 0;
    ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler subHandler;
    nl::Weave::Profiles::DataManagement::LoggingManagement & logger =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();
    nl::Weave::Profiles::DataManagement::ImportanceType importance;
    TLVWriter writer;
    uint8_t backingStore[1024];

    event_id_t eid_init_prod, eid_prev_prod, eid_init_info, eid_prev_info, eid;

    now           = System::Layer::GetClock_MonotonicMS();
    eid_init_prod = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter++);
    if (inLogInfoEvents)
    {
        eid_init_info = FastLogFreeform(nl::Weave::Profiles::DataManagement::Info, now + 5, "Freeform entry %d", counter++);
    }

    eid_prev_prod = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now + 10, "Freeform entry %d", counter++);

    if (inLogInfoEvents)
    {
        eid_prev_info = FastLogFreeform(nl::Weave::Profiles::DataManagement::Info, now + 15, "Freeform entry %d", counter++);
    }

    NL_TEST_ASSERT(inSuite, (eid_init_prod + 1) == eid_prev_prod);
    if (inLogInfoEvents)
    {
        if (nl::Weave::Profiles::DataManagement::LoggingConfiguration::GetInstance().mGlobalImportance >=
            nl::Weave::Profiles::DataManagement::Info)
        {
            NL_TEST_ASSERT(inSuite, (eid_init_info + 1) == eid_prev_info);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, eid_prev_info == 0 && eid_init_info == 0);
        }
    }

    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger) == false);
    subHandler.SetEventLogEndpoint(logger);

    importance = subHandler.FindNextImportanceForTransfer();
    NL_TEST_ASSERT(inSuite, importance == nl::Weave::Profiles::DataManagement::Production);
    writer.Init(backingStore, 1024);
    CheckLogReadOut(inSuite, context, logger, importance, eid_init_prod, 2);

    err = logger.FetchEventsSince(writer, importance, subHandler.GetVendedEvent(importance));
    NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);

    // If we expect to have logged the Info events above, check the Info logs
    if (inLogInfoEvents &&
        (nl::Weave::Profiles::DataManagement::LoggingConfiguration::GetInstance().mGlobalImportance >=
         nl::Weave::Profiles::DataManagement::Info))
    {
        importance = subHandler.FindNextImportanceForTransfer();
        NL_TEST_ASSERT(inSuite, importance == nl::Weave::Profiles::DataManagement::Info);
        writer.Init(backingStore, 1024);
        CheckLogReadOut(inSuite, context, logger, importance, eid_init_info, 2);
        err = logger.FetchEventsSince(writer, importance, subHandler.GetVendedEvent(importance));
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);
    }

    importance = subHandler.FindNextImportanceForTransfer();
    NL_TEST_ASSERT(inSuite, subHandler.VerifyTraversingImportance());

    while (importance != nl::Weave::Profiles::DataManagement::kImportanceType_Invalid)
    {
        err = logger.FetchEventsSince(writer, importance, subHandler.GetVendedEvent(importance));
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);
        importance = subHandler.FindNextImportanceForTransfer();
    }

    // Verify that events are retrieved.
    NL_TEST_ASSERT(inSuite, subHandler.VerifyTraversingImportance());
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger));

    // Check that a single event will trigger the up to date check

    eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now + 10, "Freeform entry %d", counter++);

    NL_TEST_ASSERT(inSuite, (eid_prev_prod + 1) == eid);
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger) == false);
    subHandler.SetEventLogEndpoint(logger);

    importance = subHandler.FindNextImportanceForTransfer();
    NL_TEST_ASSERT(inSuite, importance == nl::Weave::Profiles::DataManagement::Production);

    // Verify that the read operation will retrieve a single event
    eid_init_prod = subHandler.GetVendedEvent(importance);
    CheckLogReadOut(inSuite, context, logger, importance, eid_init_prod, 1);

    writer.Init(backingStore, 1024);
    while (importance != nl::Weave::Profiles::DataManagement::kImportanceType_Invalid)
    {
        err = logger.FetchEventsSince(writer, importance, subHandler.GetVendedEvent(importance));
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);
        importance = subHandler.FindNextImportanceForTransfer();
    }

    // Verify that the all events are retrieved
    NL_TEST_ASSERT(inSuite, subHandler.VerifyTraversingImportance());
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger));
}

static void CheckSubscriptionHandler(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = false;

    InitializeEventLogging(context);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

static void CheckSubscriptionHandlerCountersStartAtZeroProd(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = false;

    InitializeEventLoggingWithPersistedCounters(context, 0, nl::Weave::Profiles::DataManagement::Production);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

static void CheckSubscriptionHandlerCountersStartAtZeroTwoDifferentImportancesProd(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = true;

    InitializeEventLoggingWithPersistedCounters(context, 0, nl::Weave::Profiles::DataManagement::Production);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

static void CheckSubscriptionHandlerCountersStartAtNonZeroProd(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = false;

    InitializeEventLoggingWithPersistedCounters(context, sEventIdCounterEpoch, nl::Weave::Profiles::DataManagement::Production);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

static void CheckSubscriptionHandlerCountersStartAtNonZeroTwoDifferentImportancesProd(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = true;

    InitializeEventLoggingWithPersistedCounters(context, sEventIdCounterEpoch, nl::Weave::Profiles::DataManagement::Production);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

static void CheckSubscriptionHandlerCountersStartAtZeroInfo(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = false;

    InitializeEventLoggingWithPersistedCounters(context, 0, nl::Weave::Profiles::DataManagement::Info);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

static void CheckSubscriptionHandlerCountersStartAtZeroTwoDifferentImportancesInfo(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = true;

    InitializeEventLoggingWithPersistedCounters(context, 0, nl::Weave::Profiles::DataManagement::Info);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

static void CheckSubscriptionHandlerCountersStartAtNonZeroInfo(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = false;

    InitializeEventLoggingWithPersistedCounters(context, sEventIdCounterEpoch, nl::Weave::Profiles::DataManagement::Info);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

static void CheckSubscriptionHandlerCountersStartAtNonZeroTwoDifferentImportancesInfo(nlTestSuite * inSuite, void * inContext)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    const bool aLogInfoEvents    = true;

    InitializeEventLoggingWithPersistedCounters(context, sEventIdCounterEpoch, nl::Weave::Profiles::DataManagement::Info);

    CheckSubscriptionHandlerHelper(inSuite, context, aLogInfoEvents);
}

#if WEAVE_CONFIG_EVENT_LOGGING_EXTERNAL_EVENT_SUPPORT
static void CheckExternalEvents(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVWriter testWriter;
    TLVReader testReader;
    event_id_t eid_in, eid = 0;
    int i;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLogging(context);

    for (i = 1; i < 10; i++)
    {
        eid_in = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production,
                                                                  "Freeform entry %d", i);
    }

    // register callback
    err = LogMockExternalEvents(10, 1);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    for (i = 0; i < 10; i++)
    {
        eid_in = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production,
                                                                  "Freeform entry %d", i + 10);
    }

    // positive case where events lie within event range in importance buffer
    // retrieve all events in order

    // we make two calls to FetchEventsSince. The first one grabs all
    // the initial batch of 10 internally-stored events, and all the
    // external events.  The second one grabs the remaining 10
    // internally stored events.

    for (int j = 1; j < 3; j++)
    {
        testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
        err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
            testWriter, nl::Weave::Profiles::DataManagement::Production, eid);
        NL_TEST_ASSERT(inSuite, eid == 10 * (static_cast<event_id_t>(j) + 1));
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);

        if (context->mVerbose)
        {
            testReader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());
            nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
        }
    }

    // retrieve events starting in the middle of external events
    eid = 14;
    for (int x = 0; x < 2; x++)
    {
        testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
        err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
            testWriter, nl::Weave::Profiles::DataManagement::Production, eid);
        NL_TEST_ASSERT(inSuite, eid == 10 * (static_cast<event_id_t>(x) + 2));
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);

        if (context->mVerbose)
        {
            testReader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());
            nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
        }
    }

    // log many events so no longer trying to fetch external events
    for (i = 0; i < 100; i++)
    {
        eid_in = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production,
                                                                  "Freeform entry %d", i);
    }

    {
        utc_timestamp_t utc_tmp;
        timestamp_t time_tmp;
        event_id_t eid_tmp;

        eid = 0;
        testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
        err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
            testWriter, nl::Weave::Profiles::DataManagement::Production, eid);
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV);
        NL_TEST_ASSERT(inSuite, eid == eid_in + 1);

        testReader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());
        ReadFirstEventHeader(testReader, time_tmp, utc_tmp, eid_tmp);
        NL_TEST_ASSERT(inSuite, eid_tmp >= 20);
    }
}

static void CheckExternalEventsMultipleCallbacks(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVWriter testWriter;
    TLVReader testReader;
    event_id_t eid               = 0;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    event_id_t endingEIDs[]      = { 11, 31, 41 };
    InitializeEventLogging(context);

    err = LogMockExternalEvents(10, 1);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    for (int i = 0; i < 10; i++)
    {
        (void) nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production,
                                                                "Freeform entry %d", i);
    }

    err = LogMockExternalEvents(10, 2);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    // Note: with the current external event logging scheme, the
    // number of externally stored event segments is only limited by
    // the available buffering space.
    err = LogMockExternalEvents(10, 3);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    ClearMockExternalEvents(1);

    // even after clearing the first callback, we should receive 3 separate error codes.
    for (int j = 0; j < 3; j++)
    {
        testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
        err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
            testWriter, nl::Weave::Profiles::DataManagement::Production, eid);
        NL_TEST_ASSERT(inSuite, eid == endingEIDs[j]);
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);

        if (context->mVerbose)
        {
            testReader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());
            nl::Weave::TLV::Debug::Dump(testReader, SimpleDumpWriter);
        }
    }
}

static bool SkipEvenEvents(event_id_t aEventId)
{
    return aEventId & 1;
}

static void CheckSkipExternalEvents(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVWriter testWriter;
    TLVReader testReader;
    event_id_t eid_before, eid_after, eid = 0;
    int i;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLogging(context);
    SetShouldBlitCallback(SkipEvenEvents);

    for (i = 0; i < 10; i++)
    {
        eid_before = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production,
                                                                      "Freeform entry %d", i);
    }

    // register callback
    err = LogMockExternalEvents(10, 0);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    for (i = 0; i < 10; i++)
    {
        eid_after = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production,
                                                                     "Freeform entry %d", i + 10);
    }

    // Validate event skipping by reading back what was written.
    {
        utc_timestamp_t utc_tmp;
        timestamp_t time_tmp;
        event_id_t eid_tmp;
        unsigned count;

        // Fetch gets initial back of free form events and all external events.
        // Fetching stops after an external events block is complete.
        eid = 1;
        testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
        err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
            testWriter, nl::Weave::Profiles::DataManagement::Production, eid);
        NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
        NL_TEST_ASSERT(inSuite, eid == eid_before + 11); // Free form events plus external events

        testReader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());
        count = 0;
        while (err == WEAVE_NO_ERROR)
        {
            err = ReadFirstEventHeader(testReader, time_tmp, utc_tmp, eid_tmp);
            count++; // Also incremented on error
        }
        NL_TEST_ASSERT(inSuite, count == 16); // Initial free form events plus half of external ones

        // Fetch second block of free form events.
        eid = 21;
        testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));
        err = nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance().FetchEventsSince(
            testWriter, nl::Weave::Profiles::DataManagement::Production, eid);
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV);
        NL_TEST_ASSERT(inSuite, eid == eid_after + 1);

        testReader.Init(gLargeMemoryBackingStore, testWriter.GetLengthWritten());
        err   = WEAVE_NO_ERROR;
        count = 0;
        while (err == WEAVE_NO_ERROR)
        {
            err = ReadFirstEventHeader(testReader, time_tmp, utc_tmp, eid_tmp);
            count++; // Also incremented on error
        }
        NL_TEST_ASSERT(inSuite, count == 11); // Following free form events
    }

    SetShouldBlitCallback(NULL);
}

static void RegressionWatchdogBug(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVWriter testWriter;
    // TLVReader testReader;
    event_id_t eid = 0;
    ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler subHandler;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    nl::Weave::Profiles::DataManagement::LoggingManagement & logger =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();
    nl::Weave::Profiles::DataManagement::ImportanceType importance;

    InitializeEventLogging(context);

    err = LogMockExternalEvents(10, 1);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = LogMockExternalEvents(10, 2);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    ClearMockExternalEvents(1);
    ClearMockExternalEvents(2);
    eid = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production, "Freeform entry");

    NL_TEST_ASSERT(inSuite, eid == 21);

    testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));

    subHandler.SetEventLogEndpoint(logger);

    importance = subHandler.FindNextImportanceForTransfer();
    NL_TEST_ASSERT(inSuite, importance == nl::Weave::Profiles::DataManagement::Production);
    while (importance != nl::Weave::Profiles::DataManagement::kImportanceType_Invalid)
    {
        err = logger.FetchEventsSince(testWriter, importance, subHandler.GetVendedEvent(importance));
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);
        importance = subHandler.FindNextImportanceForTransfer();
    }
    // Verify that events are retrieved.
    NL_TEST_ASSERT(inSuite, subHandler.VerifyTraversingImportance());
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger));
}

static void RegressionWatchdogBug_EventRemoval(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVWriter testWriter;
    // TLVReader testReader;
    event_id_t eid = 0;
    timestamp_t now;
    ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler subHandler;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    nl::Weave::Profiles::DataManagement::LoggingManagement & logger =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();
    nl::Weave::Profiles::DataManagement::ImportanceType importance;

    InitializeEventLogging(context);

    err = LogMockDebugExternalEvents(10, 1);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = LogMockDebugExternalEvents(10, 2);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    eid = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Freeform entry");
    NL_TEST_ASSERT(inSuite, eid == 21);

    eid = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Freeform entry");
    NL_TEST_ASSERT(inSuite, eid == 22);

    eid = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Freeform entry");
    NL_TEST_ASSERT(inSuite, eid == 23);

    now = System::Layer::GetClock_MonotonicMS();
    for (size_t counter = 0; counter < 100; counter++)
    {
        eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);
        NL_TEST_ASSERT(inSuite, eid == counter + 1);

        now += 10;
    }

    testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));

    subHandler.SetEventLogEndpoint(logger);

    importance = subHandler.FindNextImportanceForTransfer();
    NL_TEST_ASSERT(inSuite, importance == nl::Weave::Profiles::DataManagement::Production);
    while (importance != nl::Weave::Profiles::DataManagement::kImportanceType_Invalid)
    {
        err = logger.FetchEventsSince(testWriter, importance, subHandler.GetVendedEvent(importance));
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);
        importance = subHandler.FindNextImportanceForTransfer();
    }
    // Verify that events are retrieved.
    NL_TEST_ASSERT(inSuite, subHandler.VerifyTraversingImportance());
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger));
}

static void RegressionWatchdogBug_ExternalEventState(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVWriter testWriter;
    // TLVReader testReader;
    event_id_t eid = 0;
    timestamp_t now;
    ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler subHandler;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    nl::Weave::Profiles::DataManagement::LoggingManagement & logger =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();
    nl::Weave::Profiles::DataManagement::ImportanceType importance;

    InitializeEventLogging(context);

    err = LogMockExternalEvents(10, 1);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = LogMockExternalEvents(10, 2);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    eid = nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production, "F");

    NL_TEST_ASSERT(inSuite, eid == 21);

    ClearMockExternalEvents(1);

    ClearMockExternalEvents(2);

    now = System::Layer::GetClock_MonotonicMS();
    for (size_t counter = 0; counter < 100; counter++)
    {
        eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);
        NL_TEST_ASSERT(inSuite, eid == (counter + 22));
        now += 10;
    }

    testWriter.Init(gLargeMemoryBackingStore, sizeof(gLargeMemoryBackingStore));

    subHandler.SetEventLogEndpoint(logger);

    importance = subHandler.FindNextImportanceForTransfer();
    NL_TEST_ASSERT(inSuite, importance == nl::Weave::Profiles::DataManagement::Production);
    while (importance != nl::Weave::Profiles::DataManagement::kImportanceType_Invalid)
    {
        err = logger.FetchEventsSince(testWriter, importance, subHandler.GetVendedEvent(importance));
        NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV || err == WEAVE_NO_ERROR);
        importance = subHandler.FindNextImportanceForTransfer();
    }
    // Verify that events are retrieved.
    NL_TEST_ASSERT(inSuite, subHandler.VerifyTraversingImportance());
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger));
}

static void CheckExternalEventsMultipleFetches(nlTestSuite * inSuite, void * inContext)
{
    uint8_t smallMemoryBackingStore[256];
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    TLVWriter testWriter;
    TLVReader testReader;
    event_id_t fetchId           = 0;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLogging(context);

    err = LogMockExternalEvents(10, 0);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    while ((fetchId <= 10) && (err == WEAVE_NO_ERROR))
    {
        timestamp_t time_tmp;
        utc_timestamp_t utc_tmp = 0;
        event_id_t eid_tmp      = 0;

        testWriter.Init(smallMemoryBackingStore, sizeof(smallMemoryBackingStore));
        err = LoggingManagement::GetInstance().FetchEventsSince(testWriter, Production, fetchId);
        if (fetchId <= 10)
        {
            NL_TEST_ASSERT(inSuite, err == WEAVE_ERROR_BUFFER_TOO_SMALL);
        }
        else
        {
            NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
        }

        if (err == WEAVE_ERROR_BUFFER_TOO_SMALL)
        {
            err = WEAVE_NO_ERROR;
        }

        testReader.Init(smallMemoryBackingStore, testWriter.GetLengthWritten());
        ReadFirstEventHeader(testReader, time_tmp, utc_tmp, eid_tmp);
        // eid_tmp is unsigned and so always positive
        NL_TEST_ASSERT(inSuite, eid_tmp < fetchId);
        NL_TEST_ASSERT(inSuite, utc_tmp != 0);
    }

    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
}

static event_id_t sLastExpectedExternalEventID;
static bool sExternalEventNotificationPassed;
static bool sExternalEventNotificationCalled;
static bool sExternalEventEvictionCalled;

static void ResetExternalEventDeliveryState(void)
{
    sLastExpectedExternalEventID     = 0;
    sExternalEventNotificationCalled = false;
    sExternalEventNotificationPassed = false;
    sExternalEventEvictionCalled     = false;
}

static void MockExternalEventsDelivered(ExternalEvents * inEv, event_id_t inLastDeliveredEventID, uint64_t inRecipientNodeID)
{
    sExternalEventNotificationCalled = true;
    sExternalEventNotificationPassed = (inEv->mLastEventID == sLastExpectedExternalEventID);
}

static WEAVE_ERROR MockExternalEventsFetch(EventLoadOutContext * aContext)
{
    return WEAVE_NO_ERROR;
}

static void MockExternalEventsEvicted(ExternalEvents * inEv)
{
    sExternalEventEvictionCalled = true;
}

static void CheckExternalEventNotifyDelivered(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    event_id_t eid_p, eid_d;
    event_id_t external_eid_production, external_eid_debug;
    size_t cnt = 1;
    timestamp_t now;
    ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler subHandler;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    nl::Weave::Profiles::DataManagement::LoggingManagement & logger =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    InitializeEventLogging(context);

    // Prime the event buffers with some internal events
    now   = System::Layer::GetClock_MonotonicMS();
    eid_p = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", cnt);
    eid_d = FastLogFreeform(nl::Weave::Profiles::DataManagement::Debug, now, "Freeform entry %d", cnt);

    // Register external events with production and debug importance
    err = logger.RegisterEventCallbackForImportance(nl::Weave::Profiles::DataManagement::Production, MockExternalEventsFetch,
                                                    MockExternalEventsDelivered, 10, &external_eid_production);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, external_eid_production == (eid_p + 10));

    err = logger.RegisterEventCallbackForImportance(nl::Weave::Profiles::DataManagement::Debug, MockExternalEventsFetch,
                                                    MockExternalEventsDelivered, 10, &external_eid_debug);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, external_eid_debug == (eid_d + 10));

    // Verify that we do not get a notification for an event that
    // comes before the external production event
    ResetExternalEventDeliveryState();
    sLastExpectedExternalEventID = external_eid_production;

    logger.NotifyEventsDelivered(nl::Weave::Profiles::DataManagement::Production, eid_p, 0ULL);

    NL_TEST_ASSERT(inSuite, sExternalEventNotificationCalled == false);

    // Verify we do get called for the first and last event in the external event range
    logger.NotifyEventsDelivered(nl::Weave::Profiles::DataManagement::Production, eid_p + 1, 0ULL);

    NL_TEST_ASSERT(inSuite, sExternalEventNotificationCalled);
    NL_TEST_ASSERT(inSuite, sExternalEventNotificationPassed);

    ResetExternalEventDeliveryState();
    sLastExpectedExternalEventID = external_eid_production;

    logger.NotifyEventsDelivered(nl::Weave::Profiles::DataManagement::Production, external_eid_production, 0ULL);

    NL_TEST_ASSERT(inSuite, sExternalEventNotificationCalled);
    NL_TEST_ASSERT(inSuite, sExternalEventNotificationPassed);

    // Verify that we get called when the event handler is registered and that we do not get called when event handler is
    // unregistered.  First, reset the checks notification state, and check we get a notification
    ResetExternalEventDeliveryState();
    sLastExpectedExternalEventID = external_eid_debug;

    logger.NotifyEventsDelivered(nl::Weave::Profiles::DataManagement::Debug, external_eid_debug, 0ULL);

    NL_TEST_ASSERT(inSuite, sExternalEventNotificationCalled);
    NL_TEST_ASSERT(inSuite, sExternalEventNotificationPassed);

    // Next, reset the delivery state, unregister the event handler and verify we do not get notified
    ResetExternalEventDeliveryState();

    logger.UnregisterEventCallbackForImportance(nl::Weave::Profiles::DataManagement::Debug, external_eid_debug);

    logger.NotifyEventsDelivered(nl::Weave::Profiles::DataManagement::Debug, external_eid_debug, 0ULL);

    NL_TEST_ASSERT(inSuite, sExternalEventNotificationCalled == false);
}

static void CheckExternalEventNotifyEvicted(nlTestSuite * inSuite, void * inContext)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    event_id_t eid, eid_prev;
    event_id_t external_eid_production;
    size_t counter = 0;
    timestamp_t now;
    ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler subHandler;
    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);
    nl::Weave::Profiles::DataManagement::LoggingManagement & logger =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    InitializeEventLogging(context);

    // Prime the event buffers with some internal events
    now = System::Layer::GetClock_MonotonicMS();
    eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);
    now += 10;
    counter++;

    // Register external events with production importance
    err = logger.RegisterEventCallbackForImportance(nl::Weave::Profiles::DataManagement::Production, MockExternalEventsFetch,
                                                    MockExternalEventsDelivered, MockExternalEventsEvicted, 10,
                                                    &external_eid_production);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
    NL_TEST_ASSERT(inSuite, external_eid_production == (eid + 10));

    // Force an eviction
    eid_prev = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter++);
    now += 10;
    for (; counter < 103; counter++)
    {
        // Sample production events, spaced 10 milliseconds apart
        eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);
        now += 10;

        NL_TEST_ASSERT(inSuite, eid > 0);
        NL_TEST_ASSERT(inSuite, eid == (eid_prev + 1));

        eid_prev = eid;
    }

    NL_TEST_ASSERT(inSuite, sExternalEventEvictionCalled == true);

    // Clean up
    logger.UnregisterEventCallbackForImportance(nl::Weave::Profiles::DataManagement::Production, external_eid_production);
}

#endif // WEAVE_CONFIG_EVENT_LOGGING_EXTERNAL_EVENT_SUPPORT

static void CheckShutdownLogic(nlTestSuite * inSuite, void * inContext)
{
    event_id_t eid = 0;
    int counter    = 1;
    timestamp_t now;

    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLogging(context);
    DestroyEventLogging(context);

    now = System::Layer::GetClock_MonotonicMS();

    eid = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now, "Freeform entry %d", counter);

    NL_TEST_ASSERT(inSuite, eid == 0);
}

static WEAVE_ERROR
BuildSubscribeRequest(nl::Weave::TLV::TLVWriter & writer,
                      const nl::Weave::Profiles::DataManagement::SubscriptionClient::OutEventParam & outSubscribeParam)
{
    WEAVE_ERROR err;
    SubscribeRequest::Builder request;

    err = request.Init(&writer);
    SuccessOrExit(err);

    {
        PathList::Builder & pathList = request.CreatePathListBuilder();

        pathList.EndOfPathList();
        SuccessOrExit(err = pathList.GetError());
    }

    {
        VersionList::Builder & versionList = request.CreateVersionListBuilder();

        versionList.EndOfVersionList();
        SuccessOrExit(err = versionList.GetError());
    }

    if (outSubscribeParam.mSubscribeRequestPrepareNeeded.mNeedAllEvents)
    {
        request.SubscribeToAllEvents(true);

        if (outSubscribeParam.mSubscribeRequestPrepareNeeded.mLastObservedEventListSize > 0)
        {
            EventList::Builder & eventList = request.CreateLastObservedEventIdListBuilder();

            for (size_t n = 0; n < outSubscribeParam.mSubscribeRequestPrepareNeeded.mLastObservedEventListSize; ++n)
            {
                Event::Builder & event = eventList.CreateEventBuilder();
                event.SourceId(outSubscribeParam.mSubscribeRequestPrepareNeeded.mLastObservedEventList[n].mSourceId)
                    .Importance(outSubscribeParam.mSubscribeRequestPrepareNeeded.mLastObservedEventList[n].mImportance)
                    .EventId(outSubscribeParam.mSubscribeRequestPrepareNeeded.mLastObservedEventList[n].mEventId)
                    .EndOfEvent();
                SuccessOrExit(err = event.GetError());
            }

            eventList.EndOfEventList();
            SuccessOrExit(err = eventList.GetError());
        }
    }

    request.EndOfRequest();
    SuccessOrExit(err = request.GetError());

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

exit:
    return err;
}

static void MockSubscribeRequest(nlTestSuite * inSuite,
                                 ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler & aSubHandler,
                                 const nl::Weave::Profiles::DataManagement::SubscriptionClient::OutEventParam & outSubscribeParam)
{
    WEAVE_ERROR err;
    uint8_t backingStore[1024];
    TLVWriter writer;
    TLVReader reader;
    SubscribeRequest::Parser request;
    uint32_t rejectReasonProfileId  = 0;
    uint16_t rejectReasonStatusCode = 0;

    writer.Init(backingStore, sizeof(backingStore));

    err = BuildSubscribeRequest(writer, outSubscribeParam);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    reader.Init(backingStore, writer.GetLengthWritten());

    err = reader.Next();
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = request.Init(reader);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);

    err = aSubHandler.ParsePathVersionEventLists(request, rejectReasonProfileId, rejectReasonStatusCode);
    NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
}

/*
 * This test validates that if a peer specified X as the last observed event
 * ID, the subscription handler publishes X+1 for the next event.
 */
static void CheckLastObservedEventId(nlTestSuite * inSuite, void * inContext)
{
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

    event_id_t prod_eids[3];
    event_id_t info_eids[3];

    TestLoggingContext * context = static_cast<TestLoggingContext *>(inContext);

    InitializeEventLogging(context);

    // Mock 3 production events and 3 info events
    timestamp_t now = System::Layer::GetClock_MonotonicMS();
    for (int i = 0; i < 3; i++)
    {
        prod_eids[i] = FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now + i * 10, "Prod entry %d", i);

        info_eids[i] = FastLogFreeform(nl::Weave::Profiles::DataManagement::Info, now + i * 10 + 5, "Info entry %d", i);
    }

    ::nl::Weave::Profiles::DataManagement::TestSubscriptionHandler subHandler;
    nl::Weave::Profiles::DataManagement::LoggingManagement & logger =
        nl::Weave::Profiles::DataManagement::LoggingManagement::GetInstance();

    subHandler.SetEventLogEndpoint(logger);

    // Make sure we logged all events
    CheckLogReadOut(inSuite, context, logger, nl::Weave::Profiles::DataManagement::Production, prod_eids[0], 3);
    CheckLogReadOut(inSuite, context, logger, nl::Weave::Profiles::DataManagement::Info, info_eids[0], 3);

    // We still have events to upload
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger) == false);

    // No events have been observed so the next importance should be
    // Production.
    NL_TEST_ASSERT(inSuite, subHandler.FindNextImportanceForTransfer() == nl::Weave::Profiles::DataManagement::Production);

    // Create a dummy exchange context so that SubscriptionHandler can verify
    // the local node id when parsing the Last Observed Event List in the
    // subscribe request.
    nl::Weave::ExchangeContext ec;
    ec.ExchangeMgr = static_cast<TestLoggingContext *>(inContext)->mExchangeMgr;
    subHandler.SetExchangeContext(&ec);

    // Mock Last Observed Event List
    {
        nl::Weave::Profiles::DataManagement::SubscriptionClient::OutEventParam outParam;
        nl::Weave::Profiles::DataManagement::SubscriptionClient::LastObservedEvent lastObservedEventList[2];

        // Production event
        lastObservedEventList[0].mSourceId   = kTestNodeId;
        lastObservedEventList[0].mImportance = nl::Weave::Profiles::DataManagement::Production;
        lastObservedEventList[0].mEventId    = prod_eids[2];

        // Info event
        lastObservedEventList[1].mSourceId   = kTestNodeId;
        lastObservedEventList[1].mImportance = nl::Weave::Profiles::DataManagement::Info;
        lastObservedEventList[1].mEventId    = info_eids[1];

        outParam.mSubscribeRequestPrepareNeeded.mNeedAllEvents             = true;
        outParam.mSubscribeRequestPrepareNeeded.mLastObservedEventList     = lastObservedEventList;
        outParam.mSubscribeRequestPrepareNeeded.mLastObservedEventListSize = ARRAY_SIZE(lastObservedEventList);

        MockSubscribeRequest(inSuite, subHandler, outParam);
    }

    // We still have events to process
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger) == false);

    // Since Production events were all observed, the next importance should be
    // Info
    NL_TEST_ASSERT(inSuite, subHandler.FindNextImportanceForTransfer() == nl::Weave::Profiles::DataManagement::Info);

    // Make sure vended EIDs are what we expect
    NL_TEST_ASSERT(inSuite, subHandler.GetVendedEvent(nl::Weave::Profiles::DataManagement::Production) == prod_eids[2] + 1);
    NL_TEST_ASSERT(inSuite, subHandler.GetVendedEvent(nl::Weave::Profiles::DataManagement::Info) == info_eids[1] + 1);

    // Now mock another subscribe request where all events are observed
    {
        nl::Weave::Profiles::DataManagement::SubscriptionClient::OutEventParam outParam;
        nl::Weave::Profiles::DataManagement::SubscriptionClient::LastObservedEvent lastObservedEventList[2];

        // Production event
        lastObservedEventList[0].mSourceId   = kTestNodeId;
        lastObservedEventList[0].mImportance = nl::Weave::Profiles::DataManagement::Production;
        lastObservedEventList[0].mEventId    = prod_eids[2];

        // Info event
        lastObservedEventList[1].mSourceId   = kTestNodeId;
        lastObservedEventList[1].mImportance = nl::Weave::Profiles::DataManagement::Info;
        lastObservedEventList[1].mEventId    = info_eids[2];

        outParam.mSubscribeRequestPrepareNeeded.mNeedAllEvents             = true;
        outParam.mSubscribeRequestPrepareNeeded.mLastObservedEventList     = lastObservedEventList;
        outParam.mSubscribeRequestPrepareNeeded.mLastObservedEventListSize = ARRAY_SIZE(lastObservedEventList);

        MockSubscribeRequest(inSuite, subHandler, outParam);
    }

    // No events to process
    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger) == true);
    NL_TEST_ASSERT(inSuite,
                   subHandler.FindNextImportanceForTransfer() == nl::Weave::Profiles::DataManagement::kImportanceType_Invalid);

    // Log a new event and confirm that there's more events to process
    (void) FastLogFreeform(nl::Weave::Profiles::DataManagement::Production, now + 1000, "Last Prod entry");

    subHandler.SetEventLogEndpoint(logger);

    NL_TEST_ASSERT(inSuite, subHandler.CheckEventUpToDate(logger) == false);
    NL_TEST_ASSERT(inSuite, subHandler.FindNextImportanceForTransfer() == nl::Weave::Profiles::DataManagement::Production);

    DestroyEventLogging(context);
}

// Test Suite

/**
 *  Test Suite that lists all the test functions.
 */
static const nlTest sTests[] = {
    NL_TEST_DEF("Simple Event Log Test", CheckLogEventBasics),
    NL_TEST_DEF("Simple Freeform Log Test", CheckLogFreeform),
    NL_TEST_DEF("Simple Pre-formatted Log Test", CheckLogPreformed),
    NL_TEST_DEF("Schema Generated Log Test", CheckSchemaGeneratedLogging),
    NL_TEST_DEF("Check Byte String Field Type", CheckByteStringFieldType),
    NL_TEST_DEF("Check Byte String Array", CheckByteStringArray),
    NL_TEST_DEF("Check Log eviction", CheckEvict),
    NL_TEST_DEF("Check Fetch Events", CheckFetchEvents),
    NL_TEST_DEF("Check Large Events", CheckLargeEvents),
    NL_TEST_DEF("Check Fetch Event Timestamps", CheckFetchTimestamps),
    NL_TEST_DEF("Basic Deserialization Test", CheckBasicEventDeserialization),
    NL_TEST_DEF("Complex Deserialization Test", CheckComplexEventDeserialization),
    NL_TEST_DEF("Empty Array Deserialization Test", CheckEmptyArrayEventDeserialization),
    NL_TEST_DEF("Simple Nullable Fields Test", CheckNullableFieldsSimple),
    NL_TEST_DEF("Complex Nullable Fields Test", CheckNullableFieldsComplex),
    NL_TEST_DEF("Check Deserializing an Event from a Newer Version", CheckDeserializingNewerVersion),
    NL_TEST_DEF("Check Deserializing an Event from an Older Version", CheckDeserializingOlderVersion),
    NL_TEST_DEF("Check Deserializing an Event from a Newer Version with Nullables", CheckDeserializingNewerVersionNullable),
    NL_TEST_DEF("Check Deserializing an Event from an Older Version with Nullables", CheckDeserializingOlderVersionNullable),
    NL_TEST_DEF("Subscription Handler accounting", CheckSubscriptionHandler),
    NL_TEST_DEF("Subscription Handler accounting, PersistedCounters start at zero, same importances, Production global importance",
                CheckSubscriptionHandlerCountersStartAtZeroProd),
    NL_TEST_DEF(
        "Subscription Handler accounting, PersistedCounters start at zero, two different importances, Production global importance",
        CheckSubscriptionHandlerCountersStartAtZeroTwoDifferentImportancesProd),
    NL_TEST_DEF(
        "Subscription Handler accounting, PersistedCounters start at non-zero, same importances, Production global importance",
        CheckSubscriptionHandlerCountersStartAtNonZeroProd),
    NL_TEST_DEF("Subscription Handler accounting, PersistedCounters start at non-zero, two different importances, Production "
                "global importance",
                CheckSubscriptionHandlerCountersStartAtNonZeroTwoDifferentImportancesProd),
    NL_TEST_DEF("Subscription Handler accounting, PersistedCounters start at zero, same importances, Info global importance",
                CheckSubscriptionHandlerCountersStartAtZeroInfo),
    NL_TEST_DEF(
        "Subscription Handler accounting, PersistedCounters start at zero, two different importances, Info global importance",
        CheckSubscriptionHandlerCountersStartAtZeroTwoDifferentImportancesInfo),
    NL_TEST_DEF("Subscription Handler accounting, PersistedCounters start at non-zero, same importances, Info global importance",
                CheckSubscriptionHandlerCountersStartAtNonZeroInfo),
    NL_TEST_DEF(
        "Subscription Handler accounting, PersistedCounters start at non-zero, two different importances, Info global importance",
        CheckSubscriptionHandlerCountersStartAtNonZeroTwoDifferentImportancesInfo),
#if WEAVE_CONFIG_EVENT_LOGGING_EXTERNAL_EVENT_SUPPORT
    NL_TEST_DEF("Check External Events Basic", CheckExternalEvents),
    NL_TEST_DEF("Check External Events Multiple Callbacks", CheckExternalEventsMultipleCallbacks),
    NL_TEST_DEF("Check External Events Multiple Fetches", CheckExternalEventsMultipleFetches),
    NL_TEST_DEF("Check External Events Skip", CheckSkipExternalEvents),
    NL_TEST_DEF("Check Drop Events", CheckDropEvents),
    NL_TEST_DEF("Regression: watchdog bug", RegressionWatchdogBug),
    NL_TEST_DEF("Regression: external event cleanup", RegressionWatchdogBug_EventRemoval),
    NL_TEST_DEF("Regression: external event, external clear call", RegressionWatchdogBug_ExternalEventState),
    NL_TEST_DEF("Check External Event delivery notification", CheckExternalEventNotifyDelivered),
#endif
    NL_TEST_DEF("Check Shutdown Logic", CheckShutdownLogic),
    NL_TEST_DEF("Check WDM offload trigger", CheckWDMOffloadTrigger),
    NL_TEST_DEF("Check version 1 data schema compatibility encoding + decoding", CheckVersion1DataCompatibility),
    NL_TEST_DEF("Check forward data compatibility encoding + decoding", CheckForwardDataCompatibility),
    NL_TEST_DEF("Check data incompatible encoding + decoding", CheckDataIncompatibility),
    NL_TEST_DEF("Check Gap detection", CheckGapDetection),
    NL_TEST_DEF("Check Drop Overlapping Event Id Ranges", CheckDropOverlap),
    NL_TEST_DEF("Check Last Observed Event Id", CheckLastObservedEventId),
    NL_TEST_DEF("Check External Event eviction notification", CheckExternalEventNotifyEvicted),
    NL_TEST_SENTINEL()
};

int main(int argc, char * argv[])
{
    MockPlatform::gMockPlatformClocks.GetClock_RealTime = Private::GetClock_RealTime;
    MockPlatform::gMockPlatformClocks.SetClock_RealTime = Private::SetClock_RealTime;

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

    nlTestSuite theSuite = { "weave-event-log", &sTests[0], TestSetup, TestTeardown };

    gTestLoggingContext.mReinitializeBDXUpload = true;

    // Generate machine-readable, comma-separated value (CSV) output.
    nl_test_set_output_style(OUTPUT_CSV);

    // Run test suit against one context
    nlTestRunner(&theSuite, &gTestLoggingContext);

    return nlTestRunnerStats(&theSuite);
}

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    switch (id)
    {
    case 't':
        gBDXContext.mUseTCP = true;
        break;
    case 'u':
        gBDXContext.mUseTCP = false;
        break;
    case 'D':
        gBDXContext.DestIPAddrStr = arg;
        gTestLoggingContext.bdx   = true;
        break;
    case 'p':
        if (!ParseInt(arg, gBDXContext.DestNodeId))
        {
            PrintArgError("%s: Invalid value specified for destination node id: %s\n", progName, arg);
            return false;
        }
        gTestLoggingContext.bdx = true;
        break;
    case 'd':
        gTestLoggingContext.mVerbose = true;
        break;
    case 's':
        if (!ParseInt(arg, gBDXContext.mStartingBlock))
        {
            PrintArgError("%s: Invalid value specified for start block: %s\n", progName, arg);
            return false;
        }
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

static void PrepareBinding(TestLoggingContext * context)
{
    WEAVE_ERROR err   = WEAVE_NO_ERROR;
    Binding * binding = NULL;

    if (!context->mBinding)
    {
        binding = context->mExchangeMgr->NewBinding(HandleBindingEvent, context);
        if (binding == NULL)
        {
            printf("NewBinding failed\n");
            return;
        }

        Binding::Configuration bindingConfig =
            binding->BeginConfiguration().Target_NodeId(gBDXContext.DestNodeId).Transport_UDP().Security_None();

        if (gBDXContext.DestIPAddrStr != NULL && nl::Inet::IPAddress::FromString(gBDXContext.DestIPAddrStr, gBDXContext.DestIPAddr))
        {
            bindingConfig.TargetAddress_IP(gBDXContext.DestIPAddr);

            err = bindingConfig.PrepareBinding();
            if (err != WEAVE_NO_ERROR)
            {
                printf("PrepareBinding failed\n");
                return;
            }
        }

        context->mBinding = binding;
    }
}

static WEAVE_ERROR InitSubscriptionClient(TestLoggingContext * context)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (!context->mSubClient)
    {
        err = SubscriptionEngine::GetInstance()->NewClient(&context->mSubClient, context->mBinding, NULL, NULL, NULL, 0);
    }

    return err;
}

static void HandleBindingEvent(void * const appState, const Binding::EventType event, const Binding::InEventParam & inParam,
                               Binding::OutEventParam & outParam)
{
    TestLoggingContext * context = static_cast<TestLoggingContext *>(appState);

    switch (event)
    {
    case Binding::kEvent_BindingReady:
        gLogBDXUpload.StartUpload(context->mBinding);
        break;
    case Binding::kEvent_PrepareFailed:
        printf("Binding Prepare failed\n");
        break;
    default:
        Binding::DefaultEventHandler(appState, event, inParam, outParam);
        break;
    }
}

static void StartClientConnection(System::Layer * systemLayer, void * appState, System::Error error)
{
    BDXContext * ctx = static_cast<BDXContext *>(appState);

    printf("@@@ 0 StartClientConnection entering (Con: %p)\n", Con);

    if (Con != NULL && Con->State == WeaveConnection::kState_Closed)
    {
        printf("@@@ 1 remove previous con (currently closed)\n");
        Con->Close();
        Con = NULL;
    }

    // Do nothing if a connect attempt is already in progress.
    if (Con != NULL)
    {
        printf("@@@ 2 (Con: %p) previous Con likely hanging\n", Con);
        return;
    }

    // TODO: move this to BDX logic
    Con = MessageLayer.NewConnection();
    if (Con == NULL)
    {
        printf("@@@ 3 WeaveConnection.Connect failed: no memory\n");
        return;
    }
    printf("@@@ 3+ (Con: %p)\n", Con);
    Con->OnConnectionComplete = HandleConnectionComplete;
    Con->OnConnectionClosed   = HandleConnectionClosed;

    printf("@@@ 3++ (DestNodeId: %" PRIX64 ", DestIPAddrStr: %s)\n", ctx->DestNodeId, ctx->DestIPAddrStr);

    WEAVE_ERROR err;
    if (ctx->DestIPAddrStr)
    {
        IPAddress::FromString(ctx->DestIPAddrStr, ctx->DestIPAddr);
        err = Con->Connect(ctx->DestNodeId, kWeaveAuthMode_Unauthenticated, ctx->DestIPAddr);
    }
    else // not specified, derive from NodeID
    {
        err = Con->Connect(ctx->DestNodeId);
    }

    if (err != WEAVE_NO_ERROR)
    {
        printf("@@@ 4 WeaveConnection.Connect failed: %X (%s)\n", err, ErrorStr(err));
        Con->Close();
        Con = NULL;
        return;
    }

    ConnectTry++;
    printf("@@@ 5 StartClientConnection exiting\n");
}

void HandleConnectionComplete(WeaveConnection * con, WEAVE_ERROR conErr)
{
    printf("@@@ 1 HandleConnectionComplete entering\n");

    WEAVE_ERROR err = WEAVE_NO_ERROR;
    char ipAddrStr[64];

    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

    if (conErr != WEAVE_NO_ERROR)
    {
        printf("Connection FAILED to node %" PRIX64 " (%s): %s\n", con->PeerNodeId, ipAddrStr, ErrorStr(conErr));
        con->Close();
        Con = NULL;

        if (ConnectTry < ConnectMaxTry)
        {
            err = SystemLayer.StartTimer(ConnectInterval, StartClientConnection, &gBDXContext);
            if (err != WEAVE_NO_ERROR)
            {
                printf("Inet.StartTimer failed\n");
                exit(-1);
            }
        }
        else
        {
            printf("Connection FAILED to node %" PRIX64 " (%s) after %d attempts\n", con->PeerNodeId, ipAddrStr, ConnectTry);
            exit(-1);
        }

        ClientConEstablished = false;
        return;
    }

    printf("Connection established to node %" PRIX64 " (%s)\n", con->PeerNodeId, ipAddrStr);

    ClientConEstablished = true;

    // Send the ReceiveInit or SendInit request
    if (Con != NULL)
    {
        // Kick LogBDXUpload
    }
    else
    {
        printf("Non-connection Init Requests not supported!\n");
        exit(-1);
    }

    if (err == WEAVE_NO_ERROR)
    {
        WaitingForBDXResp = true;
    }

    printf("@@@ 7 HandleConnectionComplete exiting\n");
}

void HandleConnectionClosed(WeaveConnection * con, WEAVE_ERROR conErr)
{
    char ipAddrStr[64];
    con->PeerAddr.ToString(ipAddrStr, sizeof(ipAddrStr));

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

    WaitingForBDXResp = false;

    if (Listening)
        con->Close();
    else if (con == Con)
    {
        con->Close();
        Con = NULL;
    }
}
