/*jslint node: true */
/*jslint browser: true*/
/*jslint nomen: true*/
/*global $, MP_SITE_URL*/
'use strict';

/*

Get status of the HighAvailability functionality and update header

 */

var CFE_HighAvailability = (function () {

    var haUrl, thresholdUrl, checkInterval, thresholdInterval, $wrapperObj, $modal;

    haUrl = MP_SITE_URL + '/highavailability/status';
    thresholdUrl = MP_SITE_URL + '/highavailability/threshold';
    checkInterval = 270000; // 4 min 30 sec
    thresholdInterval = 270000;

    $wrapperObj = $('.CFE_HA_STATUS');
    $modal = '';

    var getThresholdInterval = function () {
        // gets the blue host threshold time from settings
        $.ajax({
            type: 'get',
            url: thresholdUrl,
            dataType: 'json',
            cache: false
        }).done(function(data) {
           // get threshold time in s convert to ms
           thresholdInterval = data * 1000;
        });
    };

    var updateHAStatusDOM = function (domObj, status) {
        if (status === 'OK' || status === "not_active") {
            domObj.find('.ha_status').text('OK');
        }

        status = status || "degraded";

        var statusDomObj = domObj.find('.health-count');
        statusDomObj.text(status);
        $wrapperObj.find('.ha_status_wrapper').attr('data-toggle','dropdown');
        switch (status.toLowerCase()) {

        case "degraded":
            statusDomObj.text("degraded").addClass('badge badge-warning');
            domObj.addClass('degraded');
            $wrapperObj.find('.ha_status_wrapper').removeAttr('data-toggle');

            $wrapperObj.on('click', '.ha_status_wrapper', function() {
                $modal.modal('show');
            });
            break;

        case "not_active":
            statusDomObj.text("");
            domObj.addClass('not_active');
            break;

        default:
            domObj.addClass('default');
            break;
        }
    };

    var generateResultList = function (data) {
        var internalHtml = '', i;

        if (!data.length) {
            internalHtml = '<li>High Availability is not set up on your system. Please view the <a href="https://docs.cfengine.com/docs/' + CFE_MAJOR_MINOR_VERSION + '/enterprise-cfengine-guide-high-availability.html">documentation</a> for advice on how to configure it.</li>';
        } else {

            for (i = 0; i < data.length; i++) {
                internalHtml += '<li class="margin-top-small">';
                    internalHtml += '<a href="' + MP_SITE_URL + '/hosts/' + data[i][0] + '">' + data[i][1] + '</a>';
                    internalHtml += '<br /><span>Status: '+ data[i][4] + '</span>';
                    internalHtml += '<br /><span class="muted margin-top-small">State as of: ' + data[i][3] + '</span>';
                internalHtml += '</li>';
            }

        }

        internalHtml = '<ul class="unstyled">' + internalHtml + '</ul>';

        return internalHtml;
    };


    var updateHAHoverInfoDOM = function (domObj, data, status) {
        var hoverDomObj, internalHtml = '';
        hoverDomObj = domObj.find('.ha_hover_info');

        internalHtml = "<h3>HA health: "+ status +"</h3>";

        internalHtml += generateResultList(data);
        hoverDomObj.html(internalHtml);
    };

    var updateHAModalDataDOM = function (status, data) {

        $modal = $('<div id="HAHealth" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">' +
                '<div class="modal-header">' +
                    '<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="bi bi-x"></i></button>' +
                    '<h2>HA health: ' + status + '</h2>' +
                '</div>' +
                '<div class="modal-body">' +
                    generateResultList(data) +
                '</div>' +
                '<div class="modal-footer">' +
                '<button class="btn btn-large" data-dismiss="modal" onclick="">Close</button>' +
                '</div>' +
                '</div>');
    };

    var updateHACookieTime = function(time) {
        var d =  new Date();
        var exp = d.getTime() + (1 * 24 * 60 * 60 * 1000);

        $.cookie("CFE_HALastStatusCheck", time, {
            expires : exp,
            path    : '/',
            secure  : true
         });
    };

    var updateHAStatusWithCookie = function () {
        var cookieData, currentTimeMilliseconds;
        try {
            cookieData = $.parseJSON($.cookie("CFE_HALastStatusCheck"));
        } catch (e) {
            // set 0 if we cannot parse data from cookie
            cookieData = 0;
        }
        currentTimeMilliseconds = new Date().getTime();

        if ((cookieData + checkInterval) < currentTimeMilliseconds) {
            getHAStatus('','', updateHACookieTime(currentTimeMilliseconds));
        }
    };

    var getHAStatus = function(doneCallback, failCallback, alwaysCallback) {
        $.ajax({
                type: 'get',
                url: haUrl,
                dataType: 'json',
                cache: false
            }).done(function(data) {

                // some calculations here
                var status, tmpStatus = [];

                if (data.status) {
                    status = data.status;
                } else if (data.length>1) {
                    tmpStatus[0] = data[0][4];
                    tmpStatus[1] = data[1][4];

                     // check that 1 host passive, 1 host active
                    if ($.inArray("passive",tmpStatus)!=-1 && $.inArray("active",tmpStatus)!=-1) {
                        //check timestamps are not outdated
                        if (checkTimestampsOk(data)){
                            // if all ok, set status
                            status = "OK";
                        } else {
                            status = "degraded";
                        }
                    } else {
                        status = "degraded";
                    }
                } else {
                    status = "degraded";
                }

                status = status.replace('_', ' ').capitalizeFirstLetter();

                updateHAStatusDOM($wrapperObj, status);

                updateHAHoverInfoDOM($wrapperObj, data, status);

                updateHAModalDataDOM(status, data);

                if (typeof(doneCallback) === "function") {
                    doneCallback();
                }

            }).fail(function () {
                // we should say something here
                if (typeof(failCallback) === "function") {
                    failCallback();
                }
            }).always(function () {
                 if (typeof(alwaysCallback) === "function") {
                    alwaysCallback();
                };

            });
    };

    var scheduleStatusCheck = function() {
        if (HAStatusCheckTimer !== undefined) {
            clearInterval(HAStatusCheckTimer);
        }

        var HAStatusCheckTimer = setInterval(function () {
            updateHAStatusWithCookie();
        }, checkInterval);
    };

    var checkTimestampsOk = function(data) {
        var threshold = new Date();

        // subtract checkinterval from current time
        threshold.setTime(threshold.getTime()-thresholdInterval);

        var ok = true;
        var tmpTime = [];
        tmpTime[0] = data[0][3];
        tmpTime[1] = data[1][3];

        for (var x=0; x<tmpTime.length;x++) {
            if (tmpTime[x]) {

                //format and convert datetime strings to timestamps
                var str = tmpTime[x].replace(' ','T');
                // fix formatting for timezone to be parsed
                tmpTime[x] = Date.parse(str+':00');

                // compare to time minus thresholdinterval
                if (tmpTime[x]<threshold) {
                    // if outdated, change status to degraded
                    data[x][4] = "degraded";
                    ok = false;
                }
            } else {
                //no datetime found
                data[x][4] = "degraded";
                ok = false;
            }
        }
        return ok;
    };


    var init = function() {
        getThresholdInterval();
        getHAStatus();
        scheduleStatusCheck();
    };


    return {
        init: init
    };

})();


$(document).ready(function() {
    CFE_HighAvailability.init();
});
