/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

var si = require('systeminformation');
var v8 = require('v8');
var _ = require('lodash');
var URL = require('url').URL;
var constants = require('./constants.js');

module.exports = function(logger, utils) {

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

    var triggerName;
    var canaryDocID;
    var monitorStatus;
    var monitorStages = ['triggerStarted', 'triggerFired', 'triggerStopped'];

    // 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, monitoringInterval) {
        var method = 'monitor';

        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 existingTriggerID = `:_:${triggerName}`;
            var existingCanaryID = canaryDocID;

            //delete the trigger
            var triggerData = {
                apikey: apikey,
                uri: utils.uriHost + '/api/v1/namespaces/_/triggers/' + triggerName,
                triggerID: existingTriggerID
            };
            deleteTrigger(triggerData, 0);

            //delete the canary doc
            deleteDocFromDB(existingCanaryID, 0);
        }

        //create new cloudant trigger and canary doc
        var docSuffix = utils.worker + utils.host + '_' + Date.now();
        triggerName = 'cloudant_' + docSuffix;
        canaryDocID = 'canary_' + docSuffix;

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

        var triggerURL = utils.uriHost + '/api/v1/namespaces/_/triggers/' + triggerName;
        var triggerID = `:_:${triggerName}`;
        createTrigger(triggerURL, apikey)
        .then(info => {
            logger.info(method, triggerID, info);
            var newTrigger = createCloudantTrigger(triggerID, apikey);
            utils.createTrigger(newTrigger);
            setTimeout(function () {
                var canaryDoc = {
                    isCanaryDoc: true,
                    host: utils.host
                };
                createDocInDB(canaryDocID, canaryDoc);
            }, monitoringInterval / 3);
        })
        .catch(err => {
            logger.error(method, triggerID, err);
        });
    };

    function createCloudantTrigger(triggerID, apikey) {
        var method = 'createCloudantTrigger';

        var dbURL = new URL(utils.db.config.url);
        var dbName = utils.db.config.db;

        var newTrigger = {
            apikey: apikey,
            id: triggerID,
            host: dbURL.hostname,
            port: dbURL.port,
            protocol: dbURL.protocol.replace(':', ''),
            dbname: dbName,
            user: dbURL.username,
            pass: dbURL.password,
            filter: constants.MONITOR_DESIGN_DOC + '/' + constants.DOCS_FOR_MONITOR,
            query_params: {host: utils.host},
            maxTriggers: 1,
            triggersLeft: 1,
            since: 'now',
            worker: utils.worker,
            monitor: utils.host
        };

        return newTrigger;
    }

    function createTrigger(triggerURL, apikey) {
        var method = 'createTrigger';

        return new Promise(function(resolve, reject) {
            utils.authRequest({apikey: apikey}, {
                method: 'put',
                uri: triggerURL,
                json: true,
                body: {}
            }, function (error, response) {
                if (error || response.statusCode >= 400) {
                    reject('monitoring trigger create request failed');
                }
                else {
                    resolve('monitoring trigger create request was successful');
                }
            });
        });
    }

    function createDocInDB(docID, doc) {
        var method = 'createDocInDB';

        utils.db.insert(doc, docID, function (err) {
            if (!err) {
                logger.info(method, docID, 'was successfully inserted');
            }
            else {
                logger.error(method, docID, err);
            }
        });
    }

    function deleteTrigger(triggerData, retryCount) {
        var method = 'deleteTrigger';

        var triggerID = triggerData.triggerID;
        utils.authRequest(triggerData, {
            method: 'delete',
            uri: triggerData.uri
        }, function (error, response) {
            logger.info(method, triggerID, 'http delete request, STATUS:', response ? response.statusCode : undefined);
            if (error || response.statusCode >= 400) {
                if (!error && response.statusCode === 409 && retryCount < 5) {
                    logger.info(method, 'attempting to delete trigger again', triggerID, 'Retry Count:', (retryCount + 1));
                    setTimeout(function () {
                        deleteTrigger(triggerData, (retryCount + 1));
                    }, 1000);
                } else {
                    logger.error(method, triggerID, 'trigger delete request failed');
                }
            }
            else {
                logger.info(method, triggerID, 'trigger delete request was successful');
            }
        });
    }

    function deleteDocFromDB(docID, retryCount) {
        var method = 'deleteDocFromDB';

        //delete from database
        utils.db.get(docID, function (err, existing) {
            if (!err) {
                utils.db.destroy(existing._id, existing._rev, function (err) {
                    if (err) {
                        if (err.statusCode === 409 && retryCount < 5) {
                            setTimeout(function () {
                                deleteDocFromDB(docID, (retryCount + 1));
                            }, 1000);
                        }
                        else {
                            logger.error(method, docID, 'could not be deleted from the database');
                        }
                    }
                    else {
                        logger.info(method, docID, 'was successfully deleted from the database');
                    }
                });
            }
            else {
                logger.error(method, docID, 'could not be found in the database');
            }
        });
    }

};
