/* jshint node: true */
'use strict';

var Q = require('q'),
    _ = require('busyman'),
    ZSC = require('zstack-constants'),
    debug = {
        shepherd: require('debug')('zigbee-shepherd'),
        init: require('debug')('zigbee-shepherd:init'),
        request: require('debug')('zigbee-shepherd:request'),
    };

var handlers = {}, event_handlers = {};

event_handlers.attachEventHandlers = function (shepherd) {
    var controller = shepherd.controller,
        hdls = {};

    _.forEach(handlers, function (hdl, key) {
        if (key !== 'attachEventHandlers')
            hdls[key] = hdl.bind(shepherd);
    });

    controller.removeListener('SYS:resetInd',          hdls.resetInd);
    controller.removeListener('ZDO:stateChangeInd',    hdls.stateChangeInd);
    controller.removeListener('ZDO:statusErrorRsp',    hdls.statusErrorRsp);
    controller.removeListener('ZDO:leaveInd',          hdls.leaveInd);

    controller.on('SYS:resetInd',          hdls.resetInd);
    controller.on('ZDO:stateChangeInd',    hdls.stateChangeInd);
    controller.on('ZDO:statusErrorRsp',    hdls.statusErrorRsp);
    controller.on('ZDO:leaveInd',          hdls.leaveInd);
};

/*************************************************************************************************/
/*** Event Handlers                                                                            ***/
/*************************************************************************************************/
handlers.resetInd = async function (msg) {
    var self = this;

    if (this.controller.isResetting()) return;

    if (msg !== '_reset')
        debug.shepherd('Starting a software reset...');

    if(this._enabled){
        await this.stop()
        await this.start()
    }
    try {
        if (msg === '_reset')
            return self.controller.emit('_reset');
    }catch(err){
        if (msg === '_reset') {
            return self.controller.emit('_reset', err);
        } else {
            debug.shepherd('Reset had an error', err);
            self.emit('error', err);
        }
    }
};

handlers.leaveInd = function (msg) {
    // { srcaddr, extaddr, request, removechildren, rejoin }
    var dev = this._findDevByAddr(msg.extaddr);

    if (dev) {
        var ieeeAddr = dev.getIeeeAddr(),
            epList = _.cloneDeep(dev.epList);

        if (msg.request)    // request
            this._unregisterDev(dev);
        else    {
            // indication
            dev.update({status: "offline", incomplete: true});
            return Q.ninvoke(this._devbox, 'sync', dev._getId());
        }

        debug.shepherd('Device: %s leave the network.', ieeeAddr);
        this.emit('ind:leaving', epList, msg.nwkaddr, ieeeAddr);
    }else{
        this.emit('ind:leaving', epList, msg.srcaddr, msg.extaddr);
    }
};

handlers.stateChangeInd = function (msg) {
    // { state[, nwkaddr] }
    if (!msg.hasOwnProperty('nwkaddr'))
        return;

    var devStates = msg.state;

    _.forEach(ZSC.ZDO.devStates, function (statesCode, states) {
        if (msg.state === statesCode)
            devStates = states;
    });

    debug.shepherd('Device: %d is now in state: %s', msg.nwkaddr, devStates);
};

handlers.statusErrorRsp = function (msg) {
    // { srcaddr, status }
    debug.shepherd('Device: %d status error: %d', msg.srcaddr, msg.status);
};

module.exports = event_handlers;

@@ -1516,30 +1516,8 @@
 ) %7B%0A
-    var self = this;%0A%0A
     
@@ -1577,32 +1577,162 @@
 sg !== '_reset')
+%7B%0A        if(!this._enabled)%7B%0A            debug.shepherd('Skipping software reset (not started)...');%0A            return%0A        %7D
 %0A        debug.s
@@ -1771,16 +1771,22 @@
 et...');
+%0A    %7D
 %0A%0A    if
@@ -1912,36 +1912,36 @@
          return 
-self
+this
 .controller.emit
@@ -2020,20 +2020,20 @@
  return 
-self
+this
 .control
@@ -2145,12 +2145,12 @@
     
-self
+this
 .emi

reset fix