/*
 *
 *    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' },
                                       { } };

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 beforeSpacer[128];
    Schema::Nest::Test::Trait::TestETrait::TestELargeArrayNullableEvent telane = { 0 };
    uint8_t afterSpacer[128];
    uint8_t sBuffer[256];
    uint32_t sum1, sum2;
    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);
    }

    memset(beforeSpacer, 0x00, sizeof(beforeSpacer));
    memset(afterSpacer, 0x00, sizeof(afterSpacer));
    appData.mStructureData = static_cast<void *>(&telane);
    appData.mFieldSchema   = &Schema::Nest::Test::Trait::TestETrait::TestELargeArrayNullableEvent::FieldSchema;

    telane.telaneA = 0;
    telane.telaneB.num = 0;
    telane.telaneB.buf = NULL;
    telane.SetTelaneANull();
    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);
    sum1 = outer.GetLengthWritten();

    memset(beforeSpacer, 0xff, sizeof(beforeSpacer));
    memset(afterSpacer, 0xff, sizeof(afterSpacer));
    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);
    sum2 = outer.GetLengthWritten();
    NL_TEST_ASSERT(inSuite, sum1 == sum2);
}

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);

    DeallocateDeserializedStructure(&deserializedEv, &ByteStringTestEventSchema, &serializationContext);
}

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);
    }

    DeallocateDeserializedStructure(&deserializedEv, &ByteStringArrayTestEventSchema, &serializationContext);
}

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);

    nl::DeallocateEvent(&deserializedEvN, &serializationContext);
}

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);
        }

        nl::DeallocateEvent(&teN_d, &serializationContext);
    }
}

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;
    }
}
