<%
(function () {

    var log = new Log();
    var carbon = require('carbon');
    var timeRangeUtil = Packages.org.wso2.analytics.shared.util.time.TimeRangeUtils;
    var MultitenantConstants = Packages.org.wso2.carbon.base.MultitenantConstants;
    var common = require('isanalytics-common.jag');

    var CONTENT_TYPE_JSON = "application/json";
    var ALERT_TYPE = "alertType";
    var HTTP_INTERNAL_ERROR = 500;
    var HTTP_USER_NOT_AUTHENTICATED = 403;
    var alertTypeToTable = {};

    //alert types
    var ALERT_TYPE_ALL = 0;

    response.contentType = CONTENT_TYPE_JSON;
    loggedInUser = common.getLoggedInUser();

    if (loggedInUser == null) {
        log.error("User is not authenticated!");
        response.status = HTTP_USER_NOT_AUTHENTICATED;
        print('{ "status": "Failed", "message": "User is not authenticated." }');
        response.sendRedirect("/login-controller");
        return;
    }

    var connector = common.getConnector();

    var alertType = request.getParameter(ALERT_TYPE);

    if (connector != null && loggedInUser != null) {

        var categoryPath = [];
        var user = carbon.server.tenantUser(loggedInUser);
        var tenantId = user.tenantId;
        var tenantFilter = " AND meta_tenantId : [ "+ tenantId +" TO " +tenantId + " ] ";
        var superTenantId = MultitenantConstants.SUPER_TENANT_ID;

        var timeFrom = request.getParameter("timeFrom");
        var timeTo = request.getParameter("timeTo");
        var start = request.getParameter("start");
        var length = request.getParameter("length");

        if(timeFrom == null || timeTo == null) {
            var d = new Date();
            if(timeTo == null) {
                timeTo = d.getTime();
            }
            if(timeFrom == null) {
               timeFrom = d.getTime() - 3600000;
            }
        }
        var additionalParameters = request.getParameter("listnedAdditionalUserPrefs");
        var firstLoginFilter = request.getParameter("firstLogin");
        var idpType = request.getParameter("idpType");
        var idpTypeFilter = "";
        if(idpType != "") {
            idpTypeFilter = " AND identityProviderType:\"" + idpType + "\"";
        }
        var timeUnit = timeRangeUtil.getSuitableTimeRangeUnit(timeFrom, timeTo);

        if (!additionalParameters) {
            additionalParameters = "";
        }
        var query = request.getParameter("query");
        var draw = request.getParameter("draw");

        switch(query) {
            case 'summery' :

                result = {};
                var data = getSummeryResult(timeFrom, timeTo);
                populateResult(result, data, draw);
                break;
            default :
                result = {};
                 var alertDetails = getAlertResult(timeFrom, timeTo, alertType,length ,start);
                  populateResult(result, alertDetails.data, draw);
                  result.recordsFiltered = alertDetails.recordsFiltered;
                  result.recordsTotal = alertDetails.recordsTotal;
                break;
        }


        if (result) {
            if (log.isDebugEnabled()) {
                log.debug("value of result: " + result);
            }
            print(result);
        }
    }
    else {
        print('{ "status": "Failed", "statusCode": "500", "message": "AnalyticsCachedWebServiceConnector is unavailable" }');
    }


    function getSummeryResult(timeFrom, timeTo) {

        var data = [];
        // quering four tables to get the count for a specific date range
        var count = queryRecordCountIntimeRange(timeFrom, timeTo, "ORG_WSO2_IS_ANALYTICS_STREAM_LOGINSUCCESSAFTERMULTIPLEFAILURES");
        if (count > 0) {
            data.push({"key": "SuspiciousLoginAlert", "display": "Suspicious Login Alerts", "count": count});
        }

        var count = queryRecordCountIntimeRange(timeFrom, timeTo, "ORG_WSO2_IS_ANALYTICS_STREAM_LONGSESSIONS");
        if (count > 0) {
            data.push({"key": "AbnormalLongSessionAlert", "display": "Abnormal LongSession Alerts", "count": count});
        }

        return data;
    }


    function queryRecordCountIntimeRange(timeFrom, timeTo, tableName) {

        var data = [];
        var providerConfig = {};
        providerConfig.tableName = tableName;

        providerConfig.query = "_timestamp : [" + timeFrom + " TO " + timeTo + "]";
        providerConfig.limit = "";
        var timeNow = new Date().getTime();

        var data = [];
        var result = querySummeryResultForEachTable(providerConfig, 10);
        return result;
    }


    function querySummeryResultForEachTable(providerConfig, limit) {
                var tableName = providerConfig.tableName;
                var query = providerConfig.query;
                var limit = 100;
                if (providerConfig.limit) {
                    limit = providerConfig.limit;
                }

                var dataQuery = {};
                dataQuery.tableName = tableName;
                dataQuery.query = query;

                var result;
                //if there's a filter present, we should perform a Lucene search instead of reading the table
                var from = 0;
                var to = 10;

                result = connector.searchCount(loggedInUser, tableName, stringify(dataQuery)).getMessage();
                return JSON.parse(result);
     };


      function getAlertResult(timeFrom, timeTo, alertType, length ,start) {
            var data = [];
            var  providerConfig = {};
            var tableName;
            switch (alertType) {
                case "SuspiciousLoginAlert":
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_LOGINSUCCESSAFTERMULTIPLEFAILURES";
                    break;
                case "AbnormalLongSessionAlert":
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_LONGSESSIONS";
                    break;
                default:
                    alertType = "All";
                    tableName = "ORG_WSO2_IS_ANALYTICS_ALLISALERTSSTREAM";
                    break;
            }
            providerConfig.tableName = tableName;

            providerConfig.query = "_timestamp : [" + timeFrom + " TO " + timeTo + "]";
            providerConfig.limit = "";
            var timeNow = new Date().getTime();
            var data = [];
            var count = queryRecordCountIntimeRange(timeFrom, timeTo, tableName);

            var alertsList = queryAlertListResult(providerConfig, length, start);

            for (var i = 0; i < alertsList.length; i++) {
                var item = alertsList[i];
                var record = convertToAlertRecord(item, alertType);
                data.push(record);
            }
            var result = {};
            result.data = data;
            result.recordsFiltered = count;
            result.recordsTotal = count;

            return result;
    }


    function convertToAlertRecord (item, alertType) {
        var result;
        switch (alertType) {
            case "SuspiciousLoginAlert":
                 result =  {
                     "timestamp": item.timestamp,
                     "username": item.values.username,
                     "msg": item.values.msg,
                     "tenantDomain": item.values.tenantDomain
                 };
                 break;
            case "AbnormalLongSessionAlert":
                 result =  {
                     "timestamp": item.timestamp,
                     "tenantDomain": item.values.tenantDomain,
                     "username": item.values.username,
                     "duration": item.values.duration,
                     "avgDuration": item.values.avgDuration
                 };
                 break;
            case "All":
                result = {
                    "timestamp": item.timestamp,
                    "msg": item.values.msg,
                    "alertType": item.values.type,
                    "severity": item.values.severity
                };
                break;
            default:
                result = {
                    "timestamp": item.timestamp,
                    "message": item.values.msg,
                    "alertType": alertType,
                };
                break;
        }
        return result;
    }

    function hideMiddleChars(str) {
        var len = str.length;
        var result = str;
        if(len > 4) {
            result = str.substring(0,2)+'xxxx'+str.substring(len-2,len);
        }
        return result;
    }

    function populateResult(result, data, draw) {
       result.draw = draw;
       result.data = data;
    }

    /**
     * Returns Summery data.
     * @param providerConfig
     * @param limit
     */
    function querySummeryResult(providerConfig, limit) {
        var tableName = providerConfig.tableName;
        var query = providerConfig.query;
        var limit = 100;
        if (providerConfig.limit) {
            limit = providerConfig.limit;
        }

        var dataQuery = {};
        dataQuery.tableName = tableName;
        dataQuery.fieldName = "type";
        dataQuery.categoryPath =  [];
        dataQuery.query = query;
        dataQuery.scoreFunction = "1";

        var result;
        //if there's a filter present, we should perform a Lucene search instead of reading the table
        var from = 0;
        var to = 10;

        result = connector.drillDownCategories(loggedInUser, tableName, stringify(dataQuery)).getMessage();
        return JSON.parse(result);
    };

    /**
     * Returns Detailed data.
     * @param providerConfig
     * @param limit
     */
    function queryAlertListResult(providerConfig, length , start) {

        var tableName = providerConfig.tableName;
        var query = providerConfig.query;

        var dataQuery = {};
        dataQuery.tableName = tableName;
        dataQuery.query = query;
        dataQuery.count = length;
        dataQuery.start = start;

        var result;
        //if there's a filter present, we should perform a Lucene search instead of reading the table
        var from = 0;
        var to = 10;
        result = connector.search(loggedInUser, tableName, stringify(dataQuery)).getMessage();
        return JSON.parse(result);
    };
}());

%>
