// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(['hp/model/Resource', 'fs/services/alerts/AlertsService', 
        'hp/model/Session', 'hp/services/IndexFilter', 'jquery', 'hp/lib/date'],
    function(Resource, alertsService, session, IndexFilter) { "use strict";

    /*
     * We define a routine to compare alertResources.
     *   If the resources are not equal the table will end up being refreshed.
     */
    function compareAlertResources(aResource, bResource) {
        if (aResource.uri !== bResource.uri ||
                aResource.modified != bResource.modified) {
            return false;
        }

        return true;
    }
    
    var AlertResource = (function() {

        var DEFAULT_STATES = ['active', 'locked'];
        var DEFAULT_COUNT = 25;

        function AlertResource(globalView) {

            // filter specific enumerations
            var ALERT_FILTER_ENUMS = {RESOURCE_URI:0, STATE:1, SEVERITY:2, ASSIGNED_TO:3, TIME:4, LIFECYCLE:5};
            var filterVal = [];
            var self;
            var userQuery = "";

            /*
             * On IE8 the first filter request comes in as a single string not an Array
             *   Must validate that the value attribute is an array
             */
            function hasKey(key, value) {
                if ($.isArray(value)) {
                    return $.inArray(key, value) > -1;
                } else {
                    return value == key;
                }
            }

            // private
            // retrieves the severity query from the filter passed in
            function getSeverityQuery(filters) {
                var severityQuery = [];
                if(filters) {
                    if(hasKey('critical',filters)) {
                        severityQuery.push("severity='Critical'");
                    }
                    if(hasKey('warning', filters)) {
                        severityQuery.push("severity='Warning'");
                    }
                    if(hasKey('disabled', filters)) {
                        severityQuery.push("severity='Disabled'");
                    }
                    if(hasKey('informational',filters)) {
                        severityQuery.push("severity='OK'");
                    }
                    if(hasKey('unknown',filters)) {
                        severityQuery.push("severity='Unknown'");
                    }
                }

                return severityQuery.join(' OR ');
            }

            // private
            // retrieves the lifecycle query from the filter passed in
            function getLifecycleQuery(filters) {
                var lifecycleQuery = "";

                // if the lifecycle flag is true, then don't filter
                // out the lifecycle alerts
                if (filters === 'lifecycle') {
                    lifecycleQuery = "lifecycle='true'";
                }
                else if(filters === 'health')
                {
                    lifecycleQuery = "lifecycle='false'";
                }

                return lifecycleQuery;
            }

            // private
            // retrieves the user query from the filter passed in
            function getUserQuery(filters) {
                if (filters === 'mine') {
                    if (! userQuery) {
                        userQuery = "assignedToUser='" + session.getUser() + "'";
                    }
                    return userQuery;
                }

                return "";
            }

            // private
            // retrieves the state query from the filter passed in
            function getStateQuery(filters) {
                var stateQuery = [];

                if (filters) {
                    if (hasKey('active', filters)) {
                        stateQuery.push("alertState='Active'");
                    }
                    if (hasKey('cleared', filters)) {
                        stateQuery.push("alertState='Cleared'");
                    }
                    if (hasKey('locked', filters)) {  
                        stateQuery.push("alertState='Locked'");
                    }
                }

                return stateQuery.join(' OR ');
            }

            // private
            // retrieves the date query from the filter passed in
            function getDateQuery(filters) {
                var timeQuery = "";
                var today = new Date(); // sets to current date and time
                today.setHours(0,0,0,0); // set time to midnight

                if(filters.time === "today") {
                    timeQuery = "created GE '" + today.toISOString() + "'";
                } else if(filters.time === "withinLastMonth") {
                    today.setDate(today.getDate() - 30);
                    timeQuery = "created GE '" + today.toISOString() + "'";
                } else if(filters.time === "olderThan3Months") {
                    today.setDate(today.getDate() - 90);
                    timeQuery = "created LE '" + today.toISOString() + "'";
                } else if(filters.time === "olderThan1Year") {
                    today.setDate(today.getDate() - 365);
                    timeQuery = "created LE '" + today.toISOString() + "'";
                } else if(filters.time === "specificDateRange") {
                    var fromDate = new Date(filters.fromDate);
                    var toDate = new Date(filters.toDate);

                    fromDate.setHours(0,0,0,0); // set time to midnight
                    toDate.setHours(23, 59, 59, 999); // set time to 11:59 PM

                    timeQuery = "created GE '" + fromDate.toISOString() + "' AND created LE '" + toDate.toISOString() + "'";
                }

                return timeQuery;
            }

            // private
            // resets the filters
            function resetFilters() {
                filterVal[ALERT_FILTER_ENUMS.SEVERITY] = "";
                filterVal[ALERT_FILTER_ENUMS.ASSIGNED_TO] = "";
                filterVal[ALERT_FILTER_ENUMS.STATE] = "";
                filterVal[ALERT_FILTER_ENUMS.RESOURCE_URI] = "";
                filterVal[ALERT_FILTER_ENUMS.TIME] = "";
                filterVal[ALERT_FILTER_ENUMS.LIFECYCLE] = "";
            }

            // private
            // builds the query strings from the filters passed in from the presenter
            function buildQueryStrings(filters) {
                resetFilters();

                if(filters) {
                    filterVal[ALERT_FILTER_ENUMS.SEVERITY] = getSeverityQuery(filters.severity);
                    filterVal[ALERT_FILTER_ENUMS.ASSIGNED_TO] = getUserQuery(filters.user);
                    filterVal[ALERT_FILTER_ENUMS.STATE] = getStateQuery(filters.state);
                    filterVal[ALERT_FILTER_ENUMS.TIME] = getDateQuery({'time': filters.time, 'fromDate': filters.fromDate,
                        'toDate': filters.toDate});
                    filterVal[ALERT_FILTER_ENUMS.LIFECYCLE] = getLifecycleQuery(filters.category);
                    filterVal[ALERT_FILTER_ENUMS.RESOURCE_URI] = (filters.resourceUri ? filters.resourceUri : "");
                } else {
                    filterVal[ALERT_FILTER_ENUMS.RESOURCE_URI] = "";
                    filterVal[ALERT_FILTER_ENUMS.LIFECYCLE] = getLifecycleQuery('false');
                }

                // iterate through and remove empty filters before passing to the service
                var queryString = $.map(filterVal, function(current, index) {
                      if (current.length === 0) {
                          return null;
                      }
                      else {
                          return current;
                      }
                });

                return queryString;
            }

            function initFilter() {
                var filter = new IndexFilter(self.getIndexFilter());
                filter.ensureDefaults('alerts', 0, DEFAULT_COUNT);
                filter.data.defaultCount = DEFAULT_COUNT;
                filter.setProperty('state', DEFAULT_STATES);
                self.setIndexFilter(filter);
            }

            function initUserQuery() {
                var sessionUser = session.getUser();
                if (sessionUser) {
                    userQuery = "assignedToUser='" + sessionUser + "'";

                    alertsService.getAllUsers({
                        success: function(data){
                            if (data && data.members && data.members.length !== 0) {
                                var sessionUserUC = sessionUser.toUpperCase();
                                var returnedUsers = data.members;
                                var user = null;
                                for (var i = returnedUsers.length; i--;) {
                                    user = returnedUsers[i];
                                    if (sessionUserUC == user.userName.toUpperCase()) {
                                        userQuery = "assignedToUser='" + user.userName + "'";
                                        break;
                                    }
                                }
                            }
                        },
                        error: function(error) { }
                    });
                }
            }

             // Get severity from suggestions in search box.
            function getSeverityFromSearchBox(term)
            {
                term = term.toUpperCase();
                var severity = "";
    
                if ($.inArray(term, ["CRITICAL", "WARNING", "DISABLED", "INFORMATIONAL", "UNKNOWN"]) != -1)
                {
                    if(term === "INFORMATIONAL")
                    {
                        severity = "OK";
                    }
                    else if(term === "WARNING")
                    {
                        severity = "Warning";
                    } 
                    else if(term === "DISABLED")
                    {
                        severity = "Disabled";
                    } 
                    else if(term === "CRITICAL")
                    {
                        severity = "Critical";
                    }
                    else
                    {
                        severity = "Unknown";
                    }
                }
    
                return severity;
            }

            // Get state from suggestions in search box
            function getStateFromSearchBox(term)
            {
                term = term.toUpperCase();
                var state = "";
                if(term === "ACTIVE")
                {
                    state = "Active";
                }
                else if(term === "CLEARED")
                {
                    state = "Cleared";
                }
                else if(term === "LOCKED")
                {
                    state = "Locked";
                }
                return state;
            }
            
            // private 
            // Verify whether the value of severity, state, user, or lifecycle
            // in search box is valid or not. If those values are invalid, we
            // show No alerts found page.
            function checkValidStatus(properties)
            {
                if(!properties)
                {
                    return true;
                }
                
                var states = properties.state;
                if (states && states.length !== 0 && 
                        !(hasKey('active', states) || hasKey('cleared', states) || hasKey('locked', states)))
                {
                    return false;
                }
                
                var severities = properties.severity;
                if(severities && severities.length !== 0 && 
                        !(hasKey('critical',severities) || hasKey('warning', severities) ||
                          hasKey('disabled', severities) || hasKey('informational',severities) || 
                          hasKey('unknown',severities)))
                {
                    return false;
                }
                
                var user = properties.user;
                if(user && user.length !== 0 && !(user === 'mine'))
                {
                    return false;   
                }
                
                var lifecycle = properties.lifecycle;
                if(lifecycle && lifecycle.length !== 0 && 
                        !(lifecycle === 'true' || lifecycle === 'false'))
                {
                    return false;
                }
                
                return true;                
            }
            

            
            function resourceCollectionMethod(args) {
                if (!globalView) {
                    if (!(args.filter && args.filter.getProperty('resourceUri'))) {
                        args.success({category: "alerts", members: [], start: 0, count: 0, total: 0});
                        return;
                    }
                }

                var queryStrings;
                if(checkValidStatus(args.filter.data.properties))
                {
                    queryStrings = buildQueryStrings(args.filter.data.properties);
                    var sort = [args.filter.data.sort];

                    if(sort === undefined || sort[0] === undefined) {
                        sort = ['created:desc'];
                    }
                    if(sort[0] !== 'created:asc' && sort[0] !== 'created:desc') {
                        sort.push('created:desc');
                    }
                    if (args.filter.data.terms) {
                        $.each(args.filter.data.terms, function(index, term) {
                            var lowerTerm = term.toLowerCase();
                            var queryString = "(lower(description) LIKE '%25" + lowerTerm + "%25') " +
                                     "OR (lower(alerttypeid) LIKE '%25" + lowerTerm + "%25') " +
                                     "OR (lower(assignedtouser) LIKE '%25" + lowerTerm + "%25') ";
                            
                            var severity = getSeverityFromSearchBox(term);
                            if(severity.length !== 0)
                            {
                                queryString = queryString + "OR (severity = '" + severity + "')";
                            }
                            
                            var state = getStateFromSearchBox(term);                           
                            if(state.length !== 0)
                            {
                                queryString = queryString + "OR (alertState = '" + state + "')";    
                            }
                            queryStrings.push(queryString);
                        });
                    }
                    self.fire('resetStopCount');

                    args.filter.data.queryStrings = queryStrings;
                    alertsService.getAlertsByQuery(queryStrings, args.filter.data.count, sort,
                            {success : args.success, error : args.error});
                }
                else
                {
                    // If status validation fails, we return no alerts to show
                    // No alerts page.
                    self.fire('resetStopCount');
                    args.filter.data.queryStrings = queryStrings;
                    args.success({"members":[],"alertSeverityCounts":null,
                        "count":0,"total":0,"start":0,"prevPageUri":null,
                        "nextPageUri":null,"uri":null,"category":null,"created":null,
                        "modified":null,"eTag":null});  
                }
            }

            // derive from Resource
            Resource.call(this, 'alerts', {
                //Tell Resource that were defining our own collection and comparison routines
                getResourceCollectionMethod: resourceCollectionMethod,
                compareResources: compareAlertResources
            });
            
            self = this;

            initUserQuery();
            initFilter();
        }

        return AlertResource;
    }());

    return AlertResource;
});
