/*
 *
 *    Copyright (c) 2018 Google LLC.
 *    Copyright (c) 2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements a few mock event generators
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <new>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include <nlbyteorder.h>
#include "ToolCommon.h"

#include <InetLayer/Inet.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/Support/TraitEventUtils.h>

#include <MockEvents.h>

#include "schema/weave/trait/telemetry/NetworkWiFiTelemetryTrait.h"
#include <schema/weave/common/DayOfWeekEnum.h>
#include <schema/nest/test/trait/TestCommon.h>

using namespace nl::Weave::TLV;
using namespace nl::Weave::Profiles::DataManagement;
using namespace Schema::Maldives_prototype::Trait::Flintstone::NetworkWiFiTelemetryTrait;
using namespace Schema::Nest::Test::Trait::TestETrait;
using namespace Schema::Nest::Test::Trait;
using namespace Schema::Weave::Common;

#ifdef PHOENIX_RESOURCE_STRINGS
#define USER_ID_INITIAL NULL
static uint8_t kTestUserId[1]         = { 1 };
#else
#define USER_ID_INITIAL 0
static const user_id_t kTestUserId    = 0x0123456789ULL;
#endif /* PHOENIX_RESOURCE_STRINGS */

static const uint64_t kTestNodeId     = 0x18B4300001408362ULL;
static const uint64_t kTestNodeId1    = 0x18B43000002DCF71ULL;

// ResourceID helper

// tags for ResourceID structure
#ifdef PHOENIX_RESOURCE_STRINGS

WEAVE_ERROR WriteResourceID(nl::Weave::TLV::TLVWriter & writer, const uint64_t & tag, user_id_t resourceId)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    VerifyOrExit(resourceId != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);

    err = writer.PutBytes(tag, resourceId, sizeof(resourceId));
    SuccessOrExit(err);

exit:
    return err;
}

#else // PHOENIX_RESOURCE_STRINGS

WEAVE_ERROR WriteResourceID(nl::Weave::TLV::TLVWriter & writer, const uint64_t & tag, user_id_t resourceId)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    if (resourceId != 0)
        err = writer.Put(tag, resourceId);

    return err;
}
#endif // PHOENIX_RESOURCE_STRINGS


const uint32_t kLivenessTraitID           = 0x00000022;
const uint32_t kLivenessChangeEvent       = 1;
const uint64_t kLivenessDeviceStatus      = nl::Weave::TLV::ContextTag(1);

static WEAVE_ERROR WriteLivenessStatusEvent(nl::Weave::TLV::TLVWriter & writer, uint8_t inDataTag, void * anAppState)
{
    WEAVE_ERROR err =  WEAVE_NO_ERROR;
    nl::Weave::TLV::TLVType liveness;
    int32_t * context = static_cast<int32_t *>(anAppState);

    VerifyOrExit(context != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    err = writer.StartContainer(ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventData), nl::Weave::TLV::kTLVType_Structure, liveness);
    SuccessOrExit(err);

    err = writer.Put(kLivenessDeviceStatus, *context);
    SuccessOrExit(err);

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

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

exit:
    return err;
}

event_id_t LogLiveness(uint64_t inNodeID, LivenessDeviceStatus inStatus)
{
    nl::Weave::Profiles::DataManagement::EventOptions options;
    nl::Weave::Profiles::DataManagement::DetailedRootSection root;
    static EventSchema schema = {
        kLivenessTraitID,
        kLivenessChangeEvent,
        nl::Weave::Profiles::DataManagement::Production,
        1,
        1
    };
    int32_t status = static_cast<int32_t>(inStatus);

    root.ResourceID = inNodeID;
    root.TraitInstanceID = 0;

    options = EventOptions((uint32_t)0, &root, 0, nl::Weave::Profiles::DataManagement::kImportanceType_Invalid, true);

    return nl::Weave::Profiles::DataManagement::LogEvent(
        schema,
        WriteLivenessStatusEvent,
        &status,
        &options);
}

/************************************************************************/

// Pincode input trait.
const uint32_t kPincodeInputTraitID               = 0x00000e05;
const uint32_t kKeypadEntryEvent                  = 1;
const uint32_t kUserDisabledEvent                 = 2;

const uint64_t kPincodeStatus                     = nl::Weave::TLV::ContextTag(1);
const uint64_t kUserID                            = nl::Weave::TLV::ContextTag(2);
const uint64_t kInvalidEntryCount                 = nl::Weave::TLV::ContextTag(3);
const uint64_t kPincodeEntryResult                = nl::Weave::TLV::ContextTag(4);

const uint64_t kUserDisabled                      = nl::Weave::TLV::ContextTag(1);

KeypadEntryEventStruct::KeypadEntryEventStruct() :
    user_id(USER_ID_INITIAL),
    invalidEntryCount(0),
    status(0),
    entryResult(0)
{
}

UserDisabledEventStruct::UserDisabledEventStruct() :
    user_id(USER_ID_INITIAL),
    disabled(false)
{
}

static WEAVE_ERROR WriteKeypadEntryEvent(nl::Weave::TLV::TLVWriter & writer, uint8_t inDataTag, void * anAppState)
{
    WEAVE_ERROR err =  WEAVE_NO_ERROR;
    nl::Weave::TLV::TLVType keypadEntry;
    KeypadEntryEventStruct * context = static_cast<KeypadEntryEventStruct *>(anAppState);

    VerifyOrExit(context != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    err = writer.StartContainer(ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventData), nl::Weave::TLV::kTLVType_Structure, keypadEntry);
    SuccessOrExit(err);

    err = writer.Put(kPincodeStatus, context->status);
    SuccessOrExit(err);

    err = WriteResourceID(writer, kUserID, context->user_id);
    SuccessOrExit(err);

    err = writer.Put(kInvalidEntryCount, context->invalidEntryCount);
    SuccessOrExit(err);

    err = writer.Put(kPincodeEntryResult, context->entryResult);
    SuccessOrExit(err);

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

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

exit:
    return err;
}

event_id_t LogKeypadEntry(CredentialStatus inStatus, PincodeEntryResult inResult, user_id_t inUserID)
{
    static KeypadEntryEventStruct eventStruct;
    static EventSchema schema = {
        kPincodeInputTraitID,
        kKeypadEntryEvent,
        nl::Weave::Profiles::DataManagement::Production,
        1,
        1
    };

    if (inResult == PINCODE_ENTRY_RESULT_SUCCESS)
    {
        eventStruct.invalidEntryCount = 0;
    }
    else
    {
        eventStruct.invalidEntryCount++;
    }

    eventStruct.user_id = inUserID;
    eventStruct.status = inStatus;
    eventStruct.entryResult = inResult;

    return nl::Weave::Profiles::DataManagement::LogEvent(
        schema,
        WriteKeypadEntryEvent,
        &eventStruct);
}

static WEAVE_ERROR WriteUserDisabledEvent(nl::Weave::TLV::TLVWriter & writer, uint8_t inDataTag, void * anAppState)
{
    WEAVE_ERROR err =  WEAVE_NO_ERROR;
    nl::Weave::TLV::TLVType userDisabled;
    UserDisabledEventStruct * context = static_cast<UserDisabledEventStruct *>(anAppState);

    VerifyOrExit(context != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    err = writer.StartContainer(ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventData), nl::Weave::TLV::kTLVType_Structure, userDisabled);
    SuccessOrExit(err);

    err = writer.PutBoolean(kUserDisabled, context->disabled);
    SuccessOrExit(err);

    err = WriteResourceID(writer, kUserID, context->user_id);
    SuccessOrExit(err);

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

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

exit:
    return err;
}

event_id_t LogKeypadEnable(bool inEnable, user_id_t inUserID)
{
    UserDisabledEventStruct eventStruct;
    static EventSchema schema = {
        kPincodeInputTraitID,
        kUserDisabledEvent,
        nl::Weave::Profiles::DataManagement::Production,
        1,
        1
    };

    eventStruct.user_id = inUserID;
    eventStruct.disabled = !inEnable;

    return nl::Weave::Profiles::DataManagement::LogEvent(
        schema,
        WriteUserDisabledEvent,
        &eventStruct);
}

/************************************************************************/

// Bolt lock trait.

const uint32_t kBoltLockTraitID                     = 0x00000e02;
const uint32_t kBoltActuatorStateChangeEvent        = 1;

const uint64_t kBoltState                           = nl::Weave::TLV::ContextTag(1);
const uint64_t kActuatorState                       = nl::Weave::TLV::ContextTag(2);
const uint64_t kLockedState                         = nl::Weave::TLV::ContextTag(3);
const uint64_t kbolt_lock_actor                     = nl::Weave::TLV::ContextTag(4);
const uint64_t klocked_state_last_changed_at        = nl::Weave::TLV::ContextTag(5);

const uint64_t kbolt_lock_actor_method                     = nl::Weave::TLV::ContextTag(1);
const uint64_t kbolt_lock_actor_user_id                     = nl::Weave::TLV::ContextTag(2);

BoltActuatorEventStruct::BoltActuatorEventStruct() :
    state(0),
    actuatorState(0),
    lockedState(0),
    bolt_lock_actor(),
    locked_state_last_changed_at(0)
{
    return;
}

BoltLockActorStruct::BoltLockActorStruct() :
    method(0),
    user_id(USER_ID_INITIAL)
{
    return;
}

static WEAVE_ERROR WriteBoltActuatorStateChangeEvent(nl::Weave::TLV::TLVWriter & writer, uint8_t inDataTag, void * anAppState)
{
    WEAVE_ERROR err =  WEAVE_NO_ERROR;
    nl::Weave::TLV::TLVType userDisabled, lockActor;
    BoltActuatorEventStruct * context = static_cast<BoltActuatorEventStruct *>(anAppState);

    VerifyOrExit(context != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    err = writer.StartContainer(ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventData), nl::Weave::TLV::kTLVType_Structure, userDisabled);
    SuccessOrExit(err);

    err = writer.Put(kBoltState, context->state);
    SuccessOrExit(err);

    err = writer.Put(kActuatorState, context->actuatorState);
    SuccessOrExit(err);

    err = writer.Put(kLockedState, context->lockedState);
    SuccessOrExit(err);

    err = writer.StartContainer(kbolt_lock_actor, nl::Weave::TLV::kTLVType_Structure, lockActor);
    SuccessOrExit(err);

    err = writer.Put(kbolt_lock_actor_method, context->bolt_lock_actor.method);
    SuccessOrExit(err);

    err = WriteResourceID(writer, kbolt_lock_actor_user_id, context->bolt_lock_actor.user_id);
    SuccessOrExit(err);

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

    err = writer.Put(klocked_state_last_changed_at, context->locked_state_last_changed_at);
    SuccessOrExit(err);

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

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

exit:
    return err;
}

event_id_t LogBoltStateChange(BoltState inState, BoltActuatorState inActuatorState, BoltLockedState inLockedState, BoltLockActorStruct inBolt_lock_actor, utc_timestamp_t inLocked_state_last_changed_at, event_id_t inEventID)
{
    nl::Weave::Profiles::DataManagement::EventOptions options;
    BoltActuatorEventStruct eventStruct;
    static EventSchema schema = {
        kBoltLockTraitID,
        kBoltActuatorStateChangeEvent,
        nl::Weave::Profiles::DataManagement::Production,
        1,
        1
    };

    eventStruct.state = static_cast<int16_t>(inState);
    eventStruct.actuatorState = static_cast<int16_t>(inActuatorState);
    eventStruct.lockedState = static_cast<int16_t>(inLockedState);
    eventStruct.bolt_lock_actor = static_cast<BoltLockActorStruct>(inBolt_lock_actor);
    eventStruct.locked_state_last_changed_at = static_cast<uint64_t>(inLocked_state_last_changed_at);

    if (inEventID != 0)
    {
        options = EventOptions((uint32_t)0, NULL, inEventID, nl::Weave::Profiles::DataManagement::Production, false);
    }
    else
    {
        options = EventOptions();
    }


    return nl::Weave::Profiles::DataManagement::LogEvent(
        schema,
        WriteBoltActuatorStateChangeEvent,
        &eventStruct,
        &options
        );
}

/************************************************************************/

// open/close event.  Interesting because it is the canonical example of Maldives.
const uint32_t kOpenCloseTraitID = 0x235A0208;
const uint32_t kOpenCloseEvent   = 1;

const uint64_t kOpenCloseState   = nl::Weave::TLV::ContextTag(1);

static WEAVE_ERROR WriteOpenCloseEvent(nl::Weave::TLV::TLVWriter & writer, uint8_t inDataTag, void * anAppState)
{
    WEAVE_ERROR err =  WEAVE_NO_ERROR;
    nl::Weave::TLV::TLVType userDisabled;
    int32_t * context = static_cast<int32_t *>(anAppState);

    VerifyOrExit(context != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT);
    err = writer.StartContainer(ContextTag(nl::Weave::Profiles::DataManagement::kTag_EventData), nl::Weave::TLV::kTLVType_Structure, userDisabled);
    SuccessOrExit(err);

    err = writer.Put(kOpenCloseState, *context);
    SuccessOrExit(err);

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

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

exit:
    return err;
}

event_id_t LogOpenClose(OpenCloseState inState)
{
    static EventSchema schema = {
        kOpenCloseTraitID,
        kOpenCloseEvent,
        nl::Weave::Profiles::DataManagement::Production,
        1,
        1
    };
    int32_t eventState = static_cast<int32_t>(inState);

    return nl::Weave::Profiles::DataManagement::LogEvent(
        schema,
        WriteOpenCloseEvent,
        &eventState);
}

/************************************************************************/
// Event generators

EventGenerator::EventGenerator(size_t aNumStates, size_t aInitialState) :
    mNumStates(aNumStates),
    mState(aInitialState)
{
}

size_t EventGenerator::GetNumStates()
{
    return mNumStates;
}

// premiere selection of log lines from helloweave app

static const char* gLogLines[] =
{
    "Initializing weave platform",
    "StartWeave Setting LocalNodeId: 18b4300001408362",
    "Setting FabricId 93abf1086e41822",
    "Init: configuration Settings = 00000009",
    "RequestInvokeActions",
    "Init NM Daemon",
    "Watchdog ID = 1.",
    "nlWirelessCalPlatformLoadFromSysEnv: Loading From Environment for 'nlwirelessregcal.em357'",
    "setting application tag for task 0x20004148 ('NMGR') to 0x20009e20",
    "Init NM Client",
    "Waiting for events!",
    "Init pair fail: -1355284483",
    "setting application tag for task 0x20004194 ('VNCP') to 0x2000bc30",
    "Enabling watchdog tracking. ID = 2",
    "netif init",
    "[TECHBASE] \"6LoWPAN\" (0x66f6ae45) persistently enabled.",
    "[SILBS] SiLabs :: Probe - Starting 6lowpan status:0",
    "ember reset with cause 6",
    "CurrentNetwork id=NEST-PAN-1822, xPanId=B6096E5D00EBACD1, panId=be51, chan=19, nodeType=4, txPwr=-12, old status=0, new status=1, reason=0",
    "emberInitReturn (status: 0)",
    "[SILBS] HandleNetworkParametersChanged, status:1, name:NEST-PAN-1822, device role:4",
    "[SILBS] UpdateCurrentService: Creating new service",
    "[SVCBASE] NEST-PAN-1822: 1 (create) : 0 (unknown) -> 1 (idle)",
    "[SVCCTLR] NEST-PAN-1822: 0 (unknown) -> 1 (idle)",
    "[PROVCTLR] Non-partial Service \"NEST-PAN-1822\" (w/ Prov=0x1591d382) has score 3 against prov 0x1591d382.",
    "[PROVCTLR] ProvisionAction on Service \"NEST-PAN-1822\" (w/ Prov=0x1591d382) has score 3 against prov 0x1591d382.",
    "[PSKMIXIN] 0x2000a458: SetPSK set to (type:1, length16)",
    "[PROVDRVRBASE] Svc NEST-PAN-1822 matches prov 0x1591d382. Request AutoConnect.",
    "[SILBS] HandleSavedNetworkStatus: Resuming network",
    "(wpan) Thread bin.mgmt.ver:3328, stack.ver:1.0.5.0, build.ver:536 (Jun  1 2016 14:36:21)",
    "emberSetTxPowerModeReturn (status 0)",
    "CurrentNetwork id=NEST-PAN-1822, xPanId=B6096E5D00EBACD1, panId=be51, chan=19, nodeType=4, txPwr=-12, old status=0, new status=1, reason=0",
    "[SVCCTLR] RunAutoConnect: Start (1)",
    "[SVCCTLR] RunAutoConnect: Start (2)",
    "[SVCCTLR] RunAutoConnect: Start (3)",
    "[SVCCTLR] AC svc found NEST-PAN-1822: state=idle flags=auto_conn ",
    "[SVCCTLR] RunAutoConnect: 0,0",
    "[SVCCTLR] Internally-initiated connection to \"NEST-PAN-1822\" (0xb505acd3)",
    "[SVCCTLR] RunAutoConnect: Start (1)",
    "[SVCCTLR] RunAutoConnect: Start (2)",
    "[SVCCTLR] RunAutoConnect: Start (3)",
    "[SVCCTLR] RunAutoConnect: Exit due to CanProxy",
    "[SILBS] HandleNetworkParametersChanged, status:1, name:NEST-PAN-1822, device role:4",
    "[SILBS] HandleSavedNetworkStatus: In the process of resuming already.",
    "emberInitReturn (status: 0)",
    "(wpan) Thread bin.mgmt.ver:3328, stack.ver:1.0.5.0, build.ver:536 (Jun  1 2016 14:36:21)",
    "CurrentNetwork id=NEST-PAN-1822, xPanId=B6096E5D00EBACD1, panId=be51, chan=19, nodeType=4, txPwr=-12, old status=1, new status=5, reason=0",
    "resume network return (status: 0)",
    "[SILBS] Resume status:0",
    "[SVCBASE] NEST-PAN-1822: 7 (connect) : 1 (idle) -> 2 (association)",
    "[SVCCTLR] NEST-PAN-1822: 1 (idle) -> 2 (association)",
    "[SILBS] Connect: Join network NEST-PAN-1822",
    "[SILBS] HandleNetworkParametersChanged, status:5, name:NEST-PAN-1822, device role:4",
    "CurrentNetwork id=NEST-PAN-1822, xPanId=B6096E5D00EBACD1, panId=be51, chan=19, nodeType=3, txPwr=-12, old status=5, new status=5, reason=0",
    "[SILBS] HandleNetworkParametersChanged, status:5, name:NEST-PAN-1822, device role:3"
};

DebugEventGenerator::DebugEventGenerator() :
    EventGenerator(sizeof(gLogLines) / sizeof(char*), 0),
    mLogLines(gLogLines)
{
}

void DebugEventGenerator::Generate(void)
{
    nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Production, mLogLines[mState]);
    mState = (mState + 1) % mNumStates;
}

LivenessEventGenerator::LivenessEventGenerator(void) :
    EventGenerator(10, 0)
{
}

void LivenessEventGenerator::Generate(void)
{
    // Scenario: monitoring liveness for two devices -- self and remote.  Remote device goes offline and returns.
    switch (mState)
    {
    case 0:
        LogLiveness(kTestNodeId, LIVENESS_DEVICE_STATUS_ONLINE);
        break;

    case 1:
        LogLiveness(kTestNodeId1, LIVENESS_DEVICE_STATUS_ONLINE);
        break;

    case 2:
        LogLiveness(kTestNodeId, LIVENESS_DEVICE_STATUS_ONLINE);
        break;

    case 3:
        LogLiveness(kTestNodeId1, LIVENESS_DEVICE_STATUS_UNREACHABLE);
        break;

    case 4:
        LogLiveness(kTestNodeId, LIVENESS_DEVICE_STATUS_ONLINE);
        break;

    case 5:
        LogLiveness(kTestNodeId1, LIVENESS_DEVICE_STATUS_REBOOTING);
        break;

    case 6:
        LogLiveness(kTestNodeId, LIVENESS_DEVICE_STATUS_ONLINE);
        break;

    case 7:
        LogLiveness(kTestNodeId1, LIVENESS_DEVICE_STATUS_ONLINE);
        break;

    case 8:
        LogLiveness(kTestNodeId, LIVENESS_DEVICE_STATUS_ONLINE);
        break;

    case 9:
        LogLiveness(kTestNodeId1, LIVENESS_DEVICE_STATUS_ONLINE);
        break;

    default:
        mState = 0;
    }

    mState = (mState + 1) % mNumStates;
}

SecurityEventGenerator::SecurityEventGenerator(void) :
    EventGenerator(14, 0),
    mRelatedEvent(0)
{
}

void SecurityEventGenerator::Generate(void)
{
    // Scenario: debug logs are happening in the background. The user
    // of the device enters a wrong pincode, corrects it subsequently,
    // the bolt unlocks.  The door opens, and closes soon
    // thereafter. The user disables the pincode. Subsequently someone
    // else attempts to activate the keypad.

    uint64_t            now         = 0;
    now = System::Timer::GetCurrentEpoch();
    BoltLockActorStruct inBolt_lock_actor;

    switch (mState)
    {
    case 0:
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Keypad Activated");
        break;

    case 1:
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Wrong pincode: %-5d", 12345);
        break;

    case 2:
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Keypad Activated");
        break;

    case 3:
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Correct pincode: %-5d", 55555);
        break;

    case 4:
        // valid credential, trigger the BoltStateChange
        inBolt_lock_actor.method = BOLT_LOCK_ACTOR_METHOD_KEYPAD_PIN;
        inBolt_lock_actor.user_id = kTestUserId;

        LogBoltStateChange(BOLT_STATE_EXTENDED, BOLT_ACTUATOR_STATE_UNLOCKING, BOLT_LOCKED_STATE_LOCKED, inBolt_lock_actor, now, mRelatedEvent);
        break;

    case 5:
        inBolt_lock_actor.method = BOLT_LOCK_ACTOR_METHOD_KEYPAD_PIN;
        inBolt_lock_actor.user_id = kTestUserId;

        LogBoltStateChange(BOLT_STATE_RETRACTED, BOLT_ACTUATOR_STATE_OK, BOLT_LOCKED_STATE_UNLOCKED, inBolt_lock_actor, now, mRelatedEvent);

        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Successful unlock");
        break;

    case 6:

        break;

    case 7:

        break;

    case 8:
        // lets lock the door manually (no known user ID)
        inBolt_lock_actor.method = BOLT_LOCK_ACTOR_METHOD_PHYSICAL;
        inBolt_lock_actor.user_id = 0UL;
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Manual locking from inside");
        LogBoltStateChange(BOLT_STATE_RETRACTED, BOLT_ACTUATOR_STATE_LOCKING, BOLT_LOCKED_STATE_UNLOCKED, inBolt_lock_actor, now, 0);
        break;

    case 9:
        inBolt_lock_actor.method = BOLT_LOCK_ACTOR_METHOD_PHYSICAL;
        inBolt_lock_actor.user_id = 0UL;
        LogBoltStateChange(BOLT_STATE_EXTENDED, BOLT_ACTUATOR_STATE_OK, BOLT_LOCKED_STATE_LOCKED, inBolt_lock_actor, now, 0);
        break;

    case 10:
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Keypad Activated");
        break;

    case 11:
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Correct pincode: %-5d", 55555);
        break;

    case 12:
        // and disable the keypad
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Keypad disabled");
        break;

    case 13:
        // and disable the keypad
        nl::Weave::Profiles::DataManagement::LogFreeform(nl::Weave::Profiles::DataManagement::Debug, "Keypad disabled");
        break;

    default:
        mState = 0;
    }

    mState = (mState + 1) % mNumStates;
}


TelemetryEventGenerator::TelemetryEventGenerator(void) :
    EventGenerator(8, 0)
{
}

void TelemetryEventGenerator::Generate(void)
{
    NetworkWiFiStatsEvent event;
    NetworkWiFiDeauthEvent deauth;
    NetworkWiFiInvalidKeyEvent invalidkey;
    NetworkWiFiDHCPFailureEvent dhcpfail;

    event.bssid = 0x01de;
    event.freq = 11;
    event.rssi = -62;
    event.bcnRecvd = 0;
    event.bcnLost = 0;
    event.pktMCastRX = 0;
    event.pktUCastRX = 0;
    event.currRXRate = 6;
    event.currTXRate = 6;
    event.sleepTimePercent = 70;
    event.numOfAP = 1;

    // TelemetryEventGenerator generates WiFi telemetry events:
    // StatsEvent, DeauthEvent, InvalidKeyEvent and DHCPFailureEvent in sequence.
    //
    // The first 5 events are StatsEvents with bcnRecvd/pktUcastRX/sleepTimePercent updated
    // The 6th event is DeauthEvent
    // The 7th event is InvalidKeyEvent
    // The 8th event is DHCPFailureEvent

    if (mState < 5)
    {
        event.bcnRecvd += mState;
        event.pktUCastRX += mState;
        event.sleepTimePercent += mState;
        LogNetworkWiFiStatsEvent(&event, nl::Weave::Profiles::DataManagement::Production);
    }
    else if (mState == 5)
    {
        deauth.reason = -16;
        LogNetworkWiFiDeauthEvent(&deauth, nl::Weave::Profiles::DataManagement::Production);
    }
    else if (mState == 6)
    {
        invalidkey.reason = -10;
        LogNetworkWiFiInvalidKeyEvent(&invalidkey, nl::Weave::Profiles::DataManagement::Production);
    }
    else if (mState == 7)
    {
        dhcpfail.reason = -40;
        LogNetworkWiFiDHCPFailureEvent(&dhcpfail, nl::Weave::Profiles::DataManagement::Production);
    }

    mState = (mState + 1) % mNumStates;
}

TestTraitEventGenerator::TestTraitEventGenerator(void) :
    EventGenerator(3, 0)
{
    mEvent = { 0 };
    mNullableEvent = { 0 };
}

void TestTraitEventGenerator::Generate(void)
{
    static const char *kTestString = "teststring";
    switch (mState)
    {
        case 0:
            // init state
            mEvent.teA = 5;
            mEvent.teB = -5;
            mEvent.teC = true;
            mEvent.teD = ENUM_E_VALUE_1;
            mEvent.teE.seA = 200;
            mEvent.teE.seB = true;
            mEvent.teE.seC = TestCommon::COMMON_ENUM_E_VALUE_2;
            mEvent.teF = TestCommon::COMMON_ENUM_E_VALUE_1;
            mEvent.teG.seA = 200;
            mEvent.teG.seB = true;
            mEvent.teJ = -900;

            memset(&tek_buf[0], 0xAA, sizeof(tek_buf));
            mEvent.teK.mBuf = &tek_buf[0];
            mEvent.teK.mLen = sizeof(tek_buf);

            // day of week
            mEvent.teL = DAY_OF_WEEK_SUNDAY;

            //implicit resource id
            mEvent.teM = 0x18b4300000000001ULL;

            // explicit resource id
            ten_resource_type = (ten_resource_type + 1) % 8;
            {
                uint8_t *tmp = &ten_buf[0];
                nl::Weave::Encoding::LittleEndian::Write16(tmp, ten_resource_type);
                nl::Weave::Encoding::LittleEndian::Write64(tmp, mEvent.teM);
            }
            mEvent.teN.mBuf = &ten_buf[0];
            mEvent.teN.mLen = sizeof(ten_buf);

            // timestamp
            mEvent.teO = 1493336639;
            mEvent.teP = 1493336639000;

            // duration
            mEvent.teQ = -1000;
            mEvent.teR = 1000;
            mEvent.teS = 20000;

            nl::LogEvent(&mEvent);

            mNullableEvent.neA = 300;
            mNullableEvent.neB = -300;
            mNullableEvent.neC = true;
            mNullableEvent.neD = kTestString;
            mNullableEvent.neI = kTestString;
            mNullableEvent.neE = 600;
            mNullableEvent.neJ.neA = 100;
            mNullableEvent.neJ.neA = true;

            nl::LogEvent(&mNullableEvent);
            break;

        case 1:
            // day of week
            mEvent.teL ^= DAY_OF_WEEK_FRIDAY;
            nl::LogEvent(&mEvent);
            break;
        case 2:
            // implicit resource id
            ten_resource_type = (ten_resource_type + 1) % 8;
            {
                uint8_t *tmp = &ten_buf[0];
                nl::Weave::Encoding::LittleEndian::Write16(tmp, ten_resource_type);
                nl::Weave::Encoding::LittleEndian::Write64(tmp, mEvent.teM);
            }
            mEvent.teN.mBuf = &ten_buf[0];
            mEvent.teN.mLen = sizeof(ten_buf);

            nl::LogEvent(&mEvent);
            break;
        case 3:
            // timestamp/duration
            // timestamp
            mEvent.teO++;
            mEvent.teP++;

            // duration
            mEvent.teQ++;
            mEvent.teR++;
            mEvent.teS++;

            nl::LogEvent(&mEvent);
            break;
        case 4:
        default:
            // null
            mEvent.SetTeJNull();
            mEvent.SetTeMNull();
            mEvent.SetTeNNull();
            mEvent.SetTePNull();
            mEvent.SetTeSNull();

            nl::LogEvent(&mEvent);

            mNullableEvent.neJ.SetNeANull();

            nl::LogEvent(&mNullableEvent);

            mEvent.SetTeJPresent();
            mEvent.SetTeMPresent();
            mEvent.SetTeNPresent();
            mEvent.SetTePPresent();
            mEvent.SetTeSPresent();

            mNullableEvent.neJ.SetNeAPresent();
            mNullableEvent.SetNeJNull();

            nl::LogEvent(&mNullableEvent);
            break;
    }

    mState = (mState + 1) % mNumStates;
}
