<commit_before>var si = require('systeminformation');
var v8 = require('v8');
var request = require('request');
var _ = require('lodash');

module.exports = function(logger, utils) {

    // Health Endpoint
    this.endPoint = '/health';

    var triggerName;
    var monitorStatus;
    var alarmTypes = ['interval', 'date', 'cron'];
    var alarmTypeIndex = 0;
    var monitorStages = ['triggerStarted', 'triggerFired', 'triggerStopped'];
    var healthMonitor = this;

    // Health Logic
    this.health = function (req, res) {

        var stats = {triggerCount: Object.keys(utils.triggers).length};

        // get all system stats in parallel
        Promise.all([
            si.mem(),
            si.currentLoad(),
            si.fsSize(),
            si.networkStats(),
            si.inetLatency(utils.routerHost)
        ])
        .then(results => {
            stats.triggerMonitor = monitorStatus;
            stats.memory = results[0];
            stats.cpu = _.omit(results[1], 'cpus');
            stats.disk = results[2];
            stats.network = results[3];
            stats.apiHostLatency = results[4];
            stats.heapStatistics = v8.getHeapStatistics();
            res.send(stats);
        })
        .catch(error => {
            stats.error = error;
            res.send(stats);
        });
    };

    this.monitor = function(apikey) {
        var method = 'monitor';

        var auth = apikey.split(':');

        if (triggerName) {
            monitorStatus = Object.assign({}, utils.monitorStatus);
            utils.monitorStatus = {};

            var monitorStatusSize = Object.keys(monitorStatus).length;
            if (monitorStatusSize < 5) {
                //we have a failure in one of the stages
                var stageFailed = monitorStages[monitorStatusSize - 2];
                monitorStatus[stageFailed] = 'failed';
            }
            var existingID = `${apikey}/_/${triggerName}`;

            //delete trigger feed from database
            utils.sanitizer.deleteTriggerFromDB(existingID, 0);

            //delete the trigger
            var dataTrigger = {
                uri: utils.uriHost + '/api/v1/namespaces/_/triggers/' + triggerName,
                triggerID: existingID
            };
            utils.sanitizer.deleteTrigger(dataTrigger, auth, 0)
            .then((info) => {
                logger.info(method, existingID, info);
            })
            .catch(err => {
                logger.error(method, existingID, err);
            });

            var existingAlarmIndex = alarmTypes.indexOf(monitorStatus.triggerType);
            alarmTypeIndex = existingAlarmIndex !== 2 ? existingAlarmIndex + 1 : 0;
        }

        //create new alarm trigger
        triggerName = 'alarms_' + utils.worker + utils.host + '_' + Date.now();
        var alarmType = alarmTypes[alarmTypeIndex];

        //update status monitor object
        utils.monitorStatus.triggerName = triggerName;
        utils.monitorStatus.triggerType = alarmType;

        var triggerURL = utils.uriHost + '/api/v1/namespaces/_/triggers/' + triggerName;
        var triggerID = `${apikey}/_/${triggerName}`;
        healthMonitor.createTrigger(triggerURL, auth)
        .then((info) => {
            logger.info(method, triggerID, info);
            var newTrigger = healthMonitor.createAlarmTrigger(triggerID, apikey, alarmType);
            healthMonitor.createTriggerInDB(triggerID, newTrigger);
        })
        .catch(err => {
            logger.error(method, triggerID, err);
        });
    };

    this.createAlarmTrigger = function(triggerID, apikey, alarmType) {
        var method = 'createAlarmTrigger';

        var newTrigger = {
            apikey: apikey,
            name: triggerName,
            namespace: '_',
            payload: {},
            maxTriggers: -1,
            worker: utils.worker,
            monitor: utils.host
        };

        var currentDate = Date.now();
        if (alarmType === 'interval') {
            newTrigger.minutes = 1;
            newTrigger.startDate = currentDate + (1000 * 60);
            newTrigger.stopDate = currentDate + (1000 * 70);
        }
        else if (alarmType === 'date') {
            newTrigger.date = currentDate + (1000 * 60);
        }
        else {
            newTrigger.cron = '* * * * *';
            newTrigger.stopDate = currentDate + (1000 * 70);
        }

        return newTrigger;
    };

    this.createTrigger = function(triggerURL, auth) {
        var method = 'createTrigger';

        return new Promise(function(resolve, reject) {
            request({<commit_msg>fix for health monitor stopDate (#142)<commit_after>var si = require('systeminformation');
var v8 = require('v8');
var request = require('request');
var _ = require('lodash');

module.exports = function(logger, utils) {

    // Health Endpoint
    this.endPoint = '/health';

    var triggerName;
    var monitorStatus;
    var alarmTypes = ['interval', 'date', 'cron'];
    var alarmTypeIndex = 0;
    var monitorStages = ['triggerStarted', 'triggerFired', 'triggerStopped'];
    var healthMonitor = this;

    // Health Logic
    this.health = function (req, res) {

        var stats = {triggerCount: Object.keys(utils.triggers).length};

        // get all system stats in parallel
        Promise.all([
            si.mem(),
            si.currentLoad(),
            si.fsSize(),
            si.networkStats(),
            si.inetLatency(utils.routerHost)
        ])
        .then(results => {
            stats.triggerMonitor = monitorStatus;
            stats.memory = results[0];
            stats.cpu = _.omit(results[1], 'cpus');
            stats.disk = results[2];
            stats.network = results[3];
            stats.apiHostLatency = results[4];
            stats.heapStatistics = v8.getHeapStatistics();
            res.send(stats);
        })
        .catch(error => {
            stats.error = error;
            res.send(stats);
        });
    };

    this.monitor = function(apikey) {
        var method = 'monitor';

        var auth = apikey.split(':');

        if (triggerName) {
            monitorStatus = Object.assign({}, utils.monitorStatus);
            utils.monitorStatus = {};

            var monitorStatusSize = Object.keys(monitorStatus).length;
            if (monitorStatusSize < 5) {
                //we have a failure in one of the stages
                var stageFailed = monitorStages[monitorStatusSize - 2];
                monitorStatus[stageFailed] = 'failed';
            }
            var existingID = `${apikey}/_/${triggerName}`;

            //delete trigger feed from database
            utils.sanitizer.deleteTriggerFromDB(existingID, 0);

            //delete the trigger
            var dataTrigger = {
                uri: utils.uriHost + '/api/v1/namespaces/_/triggers/' + triggerName,
                triggerID: existingID
            };
            utils.sanitizer.deleteTrigger(dataTrigger, auth, 0)
            .then((info) => {
                logger.info(method, existingID, info);
            })
            .catch(err => {
                logger.error(method, existingID, err);
            });

            var existingAlarmIndex = alarmTypes.indexOf(monitorStatus.triggerType);
            alarmTypeIndex = existingAlarmIndex !== 2 ? existingAlarmIndex + 1 : 0;
        }

        //create new alarm trigger
        triggerName = 'alarms_' + utils.worker + utils.host + '_' + Date.now();
        var alarmType = alarmTypes[alarmTypeIndex];

        //update status monitor object
        utils.monitorStatus.triggerName = triggerName;
        utils.monitorStatus.triggerType = alarmType;

        var triggerURL = utils.uriHost + '/api/v1/namespaces/_/triggers/' + triggerName;
        var triggerID = `${apikey}/_/${triggerName}`;
        healthMonitor.createTrigger(triggerURL, auth)
        .then((info) => {
            logger.info(method, triggerID, info);
            var newTrigger = healthMonitor.createAlarmTrigger(triggerID, apikey, alarmType);
            healthMonitor.createTriggerInDB(triggerID, newTrigger);
        })
        .catch(err => {
            logger.error(method, triggerID, err);
        });
    };

    this.createAlarmTrigger = function(triggerID, apikey, alarmType) {
        var method = 'createAlarmTrigger';

        var newTrigger = {
            apikey: apikey,
            name: triggerName,
            namespace: '_',
            payload: {},
            maxTriggers: -1,
            worker: utils.worker,
            monitor: utils.host
        };

        var minuteInterval = 1000 * 60;
        var startDate = Date.now() + minuteInterval;
        if (alarmType === 'interval') {
            newTrigger.minutes = 1;
            newTrigger.startDate = startDate;
            newTrigger.stopDate = startDate + minuteInterval;
        }
        else if (alarmType === 'date') {
            newTrigger.date = startDate;
        }
        else {
            newTrigger.cron = '* * * * *';
            newTrigger.stopDate = startDate + minuteInterval;
        }

        return newTrigger;
    };

    this.createTrigger = function(triggerURL, auth) {
        var method = 'createTrigger';

        return new Promise(function(resolve, reject) {
            request({
{'fraction_non_alphanumeric': 0.11884276188427619, 'fraction_numerical': 0.007851150785115078, 'mean_word_length': 1.8700617283950618, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7622433', 'n_tokens_mistral': 2536, 'n_tokens_neox': 2455, 'n_words': 535}