<%
(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 TYPE = "type";
    var HTTP_INTERNAL_ERROR = 500;
    var HTTP_USER_NOT_AUTHENTICATED = 403;

    //operation types
    var TYPE_OVERALL_AUTH_SUCCESS_AND_FAILURE = 1;
    var TYPE_PER_USER_AUTH_SUCCESS = 2;
    var TYPE_PER_USER_AUTH_FAILURE = 3;
    var TYPE_PER_SERVICE_PROVIDER_AUTH_SUCCESS = 4;
    var TYPE_PER_SERVICE_PROVIDER_AUTH_FAILURE = 5;
    var TYPE_PER_ROLE_AUTH_SUCCESS = 6;
    var TYPE_PER_ROLE_AUTH_FAILURE = 7;
    var TYPE_PER_IDENTITY_PROVIDER_AUTH_SUCCESS = 9;
    var TYPE_PER_IDENTITY_PROVIDER_AUTH_FAILURE = 10;
    var TYPE_AUTHENTICATION_DATA_TABLE = 11;
    var TYPE_USERNAME_LIST = 12;
    var TYPE_SERVICE_PROVIDER_LIST = 13;
    var TYPE_IDENTITY_PROVIDER_LIST = 14;
    var TYPE_ROLE_LIST = 15;
    var TYPE_PER_SERVICE_PROVIDER_FIRST_LOGIN_SUCCESS = 16;
    var TYPE_USERSTORE_LIST = 17;
    var TYPE_PER_USERSTORE_AUTH_SUCCESS = 18;
    var TYPE_PER_USERSTORE_AUTH_FAILURE = 19;
    var TYPE_AUTHENTICATION_DATA_TABLE_RESIDENT_IDP = 20;
    var TYPE_AUTHENTICATION_DATA_TABLE_EXTERNAL = 21;
    var TYPE_PER_USER_REGION = 25;

    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 type = 0;
    var typeParam = request.getParameter(TYPE);
    if (typeParam != null) {
        type = parseInt(typeParam);
    }

    if (type == 0) {
        log.error("operation type is not specified!");
        response.status = HTTP_INTERNAL_ERROR;
        print('{ "status": "Failed", "message": "Operation type is not specified" }');
        return;
    }

    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 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 = "";
        }

        switch (type) {
            case TYPE_OVERALL_AUTH_SUCCESS_AND_FAILURE:
            {

                result = [];

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "" && additionalParameters.indexOf("identityProvider") > -1) {
                    query = stringify({
                        tableName: tableName,
                        groupByField: "facetStartTime",
                        query: "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters,
                        aggregateFields: [
                            {
                                fields: ["authStepSuccessCount"],
                                aggregate: "SUM",
                                alias: "total_authSuccessCount"
                            },
                            {
                                fields: ["authFailureCount"],
                                aggregate: "SUM",
                                alias: "total_authFailiureCount"
                            }
                        ]
                    });
                } else {
                    var successCountField = "authSuccessCount";
                    if(idpType == "FEDERATED") {
                        successCountField = "authStepSuccessCount";
                    }
                    query = stringify({
                        tableName: tableName,
                        groupByField: "facetStartTime",
                        query: "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters,
                        aggregateFields: [
                            {
                                fields: [successCountField],
                                aggregate: "SUM",
                                alias: "total_authSuccessCount"
                            },
                            {
                                fields: ["authFailureCount"],
                                aggregate: "SUM",
                                alias: "total_authFailiureCount"
                            }
                        ]
                    });
                }

                resp = connector.searchWithAggregates(superTenantId, tableName, query);
                var dataPoints = JSON.parse(resp.getMessage());

                // sort by timestamp
                var insert = function (array, rightIndex, value) {
                    for (var j = rightIndex; j > 0 && array[j - 1].values.facetStartTime[0] > value.values.facetStartTime[0]; j--) {
                        array[j] = array[j - 1];
                    }
                    array[j] = value;
                };

                for (var i = 0; i < dataPoints.length; i++) {
                    insert(dataPoints, i, dataPoints[i]);
                }

                for (var i = 0; i < dataPoints.length; i++) {
                    var obj = dataPoints[i];
                    // overallAuthSuccessCount += obj.values.total_authSuccessCount;
                    //overallAuthFailureCount += obj.values.total_authFailiureCount;

                    result.push({
                        "timestamp": obj.values.facetStartTime[0],
                        "successCount": obj.values.total_authSuccessCount,
                        "faultsCount": obj.values.total_authFailiureCount,
			            "timeUnit":timeUnit
                    });
                }

                if(dataPoints.length > 0 && !common.isStartTimestampDataAvailable(timeFrom, dataPoints[0].values.facetStartTime[0], timeUnit)) {
                    result.unshift({
                        "timestamp": timeFrom,
                        "successCount": 0,
                        "faultsCount": 0,
                        "timeUnit":timeUnit
                    });
                }
                if(dataPoints.length > 0 && !common.isEndTimestampDataAvailable(timeTo, dataPoints[dataPoints.length-1].values.facetStartTime[0], timeUnit)) {
                    result.push({
                        "timestamp": timeTo,
                        "successCount": 0,
                        "faultsCount": 0,
                        "timeUnit":timeUnit
                    });
                }
                break;
            }
            case TYPE_PER_USER_AUTH_SUCCESS:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_USERAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if(idpType == "LOCAL") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_LOCALUSERAUTHSTATPER" + timeUnit;
                }

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var scoreFunction;
                if ((additionalParameters != "" && additionalParameters.indexOf("identityProvider") > -1) || idpType == "FEDERATED") {
                    scoreFunction = "authStepSuccessCount";
                } else {
                    scoreFunction = "authSuccessCount";
                }

                var userNameField = "username";
                if(idpType == "LOCAL") {
                    userNameField = "localUsername";
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, userNameField, categoryPath, queryString, scoreFunction, start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "username": key,
                            "authSuccessCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_PER_USER_AUTH_FAILURE:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_USERAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if(idpType == "LOCAL") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_LOCALUSERAUTHSTATPER" + timeUnit;
                }

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var userNameField = "username";
                if(idpType == "LOCAL") {
                    userNameField = "localUsername";
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, userNameField, categoryPath, queryString, "authFailureCount", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "username": key,
                            "authFailiureCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_PER_SERVICE_PROVIDER_AUTH_SUCCESS:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_SPAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var scoreFunction;
                if ((additionalParameters != "" && additionalParameters.indexOf("identityProvider") > -1) || idpType == "FEDERATED") {
                    scoreFunction = "authStepSuccessCount";
                } else {
                    scoreFunction = "authSuccessCount";
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "serviceProvider", categoryPath, queryString, scoreFunction, start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "serviceProvider": key,
                            "authSuccessCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_PER_SERVICE_PROVIDER_AUTH_FAILURE:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_SPAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "serviceProvider", categoryPath, queryString, "authFailureCount", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "serviceProvider": key,
                            "authFailiureCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_PER_ROLE_AUTH_SUCCESS:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_ROLEAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                var scoreFunction;
                if (additionalParameters != "" && additionalParameters.indexOf("identityProvider") > -1) {
                    scoreFunction = "authStepSuccessCount";
                } else {
                    scoreFunction = "authSuccessCount";
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "role", categoryPath, queryString, scoreFunction, start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "role": key,
                            "authSuccessCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_PER_ROLE_AUTH_FAILURE:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_ROLEAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "role", categoryPath, queryString, "authFailureCount", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "role": key,
                            "authFailiureCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_PER_IDENTITY_PROVIDER_AUTH_SUCCESS:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }
                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_IDPAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var scoreFunction;
                if ((additionalParameters != "" && additionalParameters.indexOf("identityProvider") > -1) || idpType == "FEDERATED") {
                    scoreFunction = "authStepSuccessCount";
                } else {
                    scoreFunction = "authSuccessCount";
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "identityProvider", categoryPath, queryString, scoreFunction, start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "identityProvider": key,
                            "authSuccessCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_PER_IDENTITY_PROVIDER_AUTH_FAILURE:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_IDPAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "identityProvider", categoryPath, queryString, "authFailureCount", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "identityProvider": key,
                            "authFailiureCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_AUTHENTICATION_DATA_TABLE:
            {

                var columns = ["contextId", "username", "serviceProvider", "identityProvider", "rolesCommaSeparated",
                    "tenantDomain" , "remoteIp", "region", "authenticationSuccess", "_timestamp"];
                var result = {};
                var data = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("length"));
                var draw = request.getParameter("draw");

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_PROCESSEDOVERALLAUTHENTICATION";
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + firstLoginFilter + additionalParameters ;

                if ((additionalParameters != "" && additionalParameters.indexOf("identityProvider") > -1)) {
                    queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + firstLoginFilter + additionalParameters ;
                }

                queryString += " AND ((eventType:step AND authStepSuccess:false) OR (eventType:overall AND authenticationSuccess:true))";

                var query;
                if(request.getParameter("order[0][column]") != null) {
                    var sortByColumnNo = parseInt(request.getParameter("order[0][column]"));
                    var sortType = request.getParameter("order[0][dir]").toUpperCase();

                    query = stringify({
                        "query": queryString,
                        "start": start,
                        "count": length,
                        "sortBy": [
                            {
                                "field": columns[sortByColumnNo],
                                "sortType": sortType
                            }
                        ]
                    });
                } else {
                    query = stringify({
                        "query": queryString,
                        "start": start,
                        "count": length
                    });
                }

                var resp = connector.search(superTenantId, tableName, query);
                var dataPoints = JSON.parse(resp.getMessage());

                var count = connector.searchCount(superTenantId, tableName, query);
                var limit = count.getMessage();

                for (i = 0; i < dataPoints.length; i++) {
                    var temp = [];

                    for (j = 0; j < columns.length; j++) {
                        var column = columns[j];
                        if (dataPoints[i] != null) {
                            if (column == "_timestamp") {
                                var value = dataPoints[i]["timestamp"];
                                var date = new Date(value);
                                temp.push(date.toLocaleString());
                            } else {
                                var value = dataPoints[i]["values"][column];
                                temp.push(value);
                            }
                        }
                    }
                    data.push(temp);
                }

                result["draw"] = draw;
                result["data"] = data;

                if (dataPoints.length < length) {
                    limit = start + dataPoints.length;
                }
                result["recordsFiltered"] = limit;
                result["recordsTotal"] = limit;
                break;
            }
            case TYPE_USERNAME_LIST:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_USERAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var userNameField = "username";
                if(idpType == "FEDERATED") {
                    userNameField = "localUsername";
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, userNameField, categoryPath, queryString, "", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        result.push({
                            "username": key
                        });
                    }
                }
                break;
            }
            case TYPE_ROLE_LIST:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_ROLEAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "role", categoryPath, queryString, "", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        result.push({
                            "role": key
                        });
                    }
                }
                break;
            }
            case TYPE_IDENTITY_PROVIDER_LIST :
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_IDPAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "identityProvider", categoryPath, queryString, "", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        result.push({
                            "identityProvider": key
                        });
                    }
                }
                break;
            }
            case TYPE_SERVICE_PROVIDER_LIST :
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_SPAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "serviceProvider", categoryPath, queryString, "", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        result.push({
                            "serviceProvider": key
                        });
                    }
                }
                break;
            }
            case TYPE_USERSTORE_LIST:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_USERSTOREAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "userStoreDomain", categoryPath, queryString, "", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        result.push({
                            "userstore": key
                        });
                    }
                }
                break;
            }
            case TYPE_PER_USERSTORE_AUTH_SUCCESS:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_USERSTOREAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var scoreFunction;
                if (additionalParameters != "" && additionalParameters.indexOf("identityProvider") > -1) {
                    scoreFunction = "authStepSuccessCount";
                } else {
                    scoreFunction = "authSuccessCount";
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "userStoreDomain", categoryPath, queryString, scoreFunction, start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "userstore": key,
                            "authSuccessCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_PER_USERSTORE_AUTH_FAILURE:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_USERSTOREAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);

                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "userStoreDomain", categoryPath, queryString, "authFailureCount", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "userstore": key,
                            "authFailiureCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }
            case TYPE_AUTHENTICATION_DATA_TABLE_RESIDENT_IDP:
            {
                var columns = ["contextId", "localUsername", "serviceProvider", "userStoreDomain", "tenantDomain", "rolesCommaSeparated"
                    , "remoteIp", "region", "authenticationSuccess", "_timestamp"];
                var result = {};
                var data = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("length"));
                var draw = request.getParameter("draw");

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_PROCESSEDOVERALLAUTHENTICATION";
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);
                var queryString = " AND ((eventType:step AND authStepSuccess:false) OR (eventType:overall AND authenticationSuccess:true)) ";

                var query;
                if(request.getParameter("order[0][column]") != null) {

                    var sortByColumnNo = parseInt(request.getParameter("order[0][column]"));
                    var sortType = request.getParameter("order[0][dir]").toUpperCase();

                    query = stringify({
                        "query": "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + queryString + additionalParameters ,
                        "start": start,
                        "count": length,
                        "sortBy": [
                            {
                                "field": columns[sortByColumnNo],
                                "sortType": sortType
                            }
                        ]
                    });
                } else {
                    query = stringify({
                        "query": "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + queryString + additionalParameters ,
                        "start": start,
                        "count": length
                    });
                }

                var resp = connector.search(superTenantId, tableName, query);
                var dataPoints = JSON.parse(resp.getMessage());
                var count = connector.searchCount(superTenantId, tableName, query);
                var limit = count.getMessage();

                for (i = 0; i < dataPoints.length; i++) {
                    var temp = [];

                    for (j = 0; j < columns.length; j++) {
                        var column = columns[j];
                        if (dataPoints[i] != null) {
                            if (column == "_timestamp") {
                                var value = dataPoints[i]["timestamp"];
                                var date = new Date(value);
                                temp.push(date.toLocaleString());
                            } else {
                                var value = dataPoints[i]["values"][column];
                                temp.push(value);
                            }
                        }
                    }
                    data.push(temp);
                }

                result["draw"] = draw;
                result["data"] = data;

                if (dataPoints.length < length) {
                    limit = start + dataPoints.length;
                }
                result["recordsFiltered"] = limit;
                result["recordsTotal"] = limit;
                break;
            }
            case TYPE_AUTHENTICATION_DATA_TABLE_EXTERNAL:
            {
                var columns = ["contextId", "username", "serviceProvider", "identityProvider",
                    "remoteIp", "region", "authStepSuccess", "_timestamp"];
                var result = {};
                var data = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("length"));
                var draw = request.getParameter("draw");

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_PROCESSEDOVERALLAUTHENTICATION";
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);
                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters ;

                if ((additionalParameters != "" && additionalParameters.indexOf("identityProvider") > -1) || idpType == "FEDERATED") {
                    queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + " AND eventType:\"step\" " + idpTypeFilter + firstLoginFilter + additionalParameters ;
                }

                var query;
                if(request.getParameter("order[0][column]") != null) {
                    var sortByColumnNo = parseInt(request.getParameter("order[0][column]"));
                    var sortType = request.getParameter("order[0][dir]").toUpperCase();

                    query = stringify({
                        "query": queryString,
                        "start": start,
                        "count": length,
                        "sortBy": [
                            {
                                "field": columns[sortByColumnNo],
                                "sortType": sortType
                            }
                        ]
                    });
                } else {
                    query = stringify({
                        "query": queryString,
                        "start": start,
                        "count": length
                    });
                }



                var resp = connector.search(superTenantId, tableName, query);
                var dataPoints = JSON.parse(resp.getMessage());

                var count = connector.searchCount(superTenantId, tableName, query);
                var limit = count.getMessage();

                for (i = 0; i < dataPoints.length; i++) {
                    var temp = [];

                    for (j = 0; j < columns.length; j++) {
                        var column = columns[j];
                        if (dataPoints[i] != null) {
                            if (column == "_timestamp") {
                                var value = dataPoints[i]["timestamp"];
                                var date = new Date(value);
                                temp.push(date.toLocaleString());
                            } else {
                                var value = dataPoints[i]["values"][column];
                                temp.push(value);
                            }
                        }
                    }
                    data.push(temp);
                }

                result["draw"] = draw;
                result["data"] = data;

                if (dataPoints.length < length) {
                    limit = start + dataPoints.length;
                }
                result["recordsFiltered"] = limit;
                result["recordsTotal"] = limit;
                break;
            }
            case TYPE_PER_SERVICE_PROVIDER_FIRST_LOGIN_SUCCESS :
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_SPAUTHSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);
                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;
                var queryResult = common.getDrillDownResult(tableName, "serviceProvider", categoryPath, queryString, "authFirstSuccessCount", start, length);

                var obj = queryResult[0];

                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        dataPointsArray.push({
                            "serviceProvider": key,
                            "authSuccessCount": obj[key]
                        });
                    }
                }
                result.push(dataPointsArray);
                result.push(queryResult[1]);
                break;
            }


            case TYPE_PER_USER_REGION:
            {
                result = [];
                dataPointsArray = [];
                var start = parseInt(request.getParameter("start"));
                var length = parseInt(request.getParameter("count"));

                if (timeUnit == "SECOND") {
                    timeUnit = "MINUTE";
                }

                var tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_USERREGIONSTATPER" + timeUnit;
                timeFrom = timeRangeUtil.getFloorValueForTimeStamp(timeFrom, timeUnit);
                if (additionalParameters != "") {
                    tableName = "ORG_WSO2_IS_ANALYTICS_STREAM_AUTHSTATPER" + timeUnit;
                }

                var queryString = "_timestamp : [" + timeFrom + " TO " + timeTo + "]" + tenantFilter + idpTypeFilter + firstLoginFilter + additionalParameters;

                var scoreFunctions = ["authSuccessCount", "authFailureCount"]

                for (var i = 0; i < scoreFunctions.length; i++) {

                    var queryResult = common.getDrillDownResult(tableName, "region", categoryPath, queryString, scoreFunctions[i], start, length);

                    var obj = queryResult[0];

                    if ( i == 0) {
                        for (var key in obj) {
                            if (obj.hasOwnProperty(key) && key != "EMPTY_FACET_VALUE!") {
                                result.push({
                                    "region": key,
                                    "authSuccessCount": obj[key]
                                });
                            }
                        }
                    } else if (i == 1) {
                        for (var key in obj) {
                            if (obj.hasOwnProperty(key) && key != "EMPTY_FACET_VALUE!") {
                                result.push({
                                    "region": key,
                                    "authFailureCount": obj[key]
                                });
                            }
                        }
                    }
                }

                break;
            }
            default:
            {
                result = '{ "status": "Failed", "message": "Unidentified operation" }';
            }
        }

        if (result != null) {
            if (log.isDebugEnabled()) {
                log.debug("value of result: " + result);
            }
            var finalResult;
            if (type == TYPE_AUTHENTICATION_DATA_TABLE || type == TYPE_AUTHENTICATION_DATA_TABLE_RESIDENT_IDP || type == TYPE_AUTHENTICATION_DATA_TABLE_EXTERNAL) {
                finalResult = result;
            } else {
                finalResult = {
                    status: "success",
                    message: result
                }
            }
            print(finalResult);
        }
    }
    else {
        print('{ "status": "Failed", "statusCode": "500", "message": "AnalyticsCachedWebServiceConnector is unavailable" }');
    }
}());

%>