// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
/**
 * @type {TasksPresenter}
 */
define(['hpsum/model/activity/ActivityResource',
    'hp/services/IndexService',
    'hp/core/Router',
    'hp/model/Session',
    'hp/services/REST',
    'hp/core/UrlFragment',
    'hp/services/IndexFilter',
    'hp/model/DevelopmentSettings',
    'hp/core/EventDispatcher',
    'hp/core/Localizer'], 
function(resource, indexService, router, session, REST, urlFragment, IndexFilter, settings, EventDispatcher, localizer) {"use strict";

    var ActivityPresenter = ( function() {
      
        var STATES = ['pending', 'running', 'finished', 'active', 'cleared'];
        var STATUSES = ['error', 'warning', 'ok', 'unknown'];
        var DEFAULT_STATES = ['pending', 'running', 'active'];
        var DEFAULT_GLOBAL_STATUSES = ['error', 'warning', 'unknown'];
        var DEFAULT_RESOURCE_STATUSES = ['error', 'warning', 'ok', 'unknown'];
        var DEFAULT_CATEGORY = 'all';

        /**
         * @constructor
         */
        function ActivityPresenter() {
          
            var dispatcher = new EventDispatcher();
            var timer;
            var useRoutes = false;
            var initialized = false;
            
            function onIndexResultsChange(indexResults) {
                dispatcher.fire("indexResultsChange", indexResults);
            }
            
            function onSelectionChange(uris) {
                dispatcher.fire("selectionChange", uris);
                if (uris && uris.length > 0) {
                    // no multi-select yet
                    resource.getItem(uris[0], {
                        success: function (item) {
                            dispatcher.fire("itemChange", item);
                        },
                        error: function (errorMessage) {
                            dispatcher.fire("itemError", errorMessage);
                        }
                    });
                }
            }
            
            function getIndexResults(handlers) {
                resource.getIndexResults(handlers);
            }
            
            function onFilterChange(filter) {
                dispatcher.fire("filterChange", filter);
            }
            
            function onRouteChange(location) {
                var uris = urlFragment.getUris(location);
                var multiSelectId = urlFragment.getMultiSelectId(location);
                var newFilter = new IndexFilter(location);
                var load = resource.setIndexFilter(newFilter);
                
                if (load) {
                    // filter changed, reset selection
                    resource.clearSelectedUris();
                }
                
                if (uris && uris.length > 0) {
                    resource.setSelectedUris(uris);
                    // see if we know about the selection already
                    var cached = $.grep(uris, function (uri) {
                        return resource.getIndexResultForUri(uri);
                    });
                    if (cached.length !== uris.length) {
                        load = true;
                    }
                }
                else if (multiSelectId) {
                    if (! resource.selectMultiSelectId(multiSelectId)) {
                        load = true;
                    }
                } else {
                    load = true;
                }
                
                if (load) {
                    getIndexResults();
                }
            }
            
            function areSame(arr1, arr2) {
                return ($(arr1).not(arr2).length == 0 &&
                    $(arr2).not(arr1).length == 0);
            }
            
            // http://www.falsepositives.com/index.php/2009/12/01/javascript-function-to-get-the-intersect-of-2-arrays/
            function getIntersect(arr1, arr2) {
                var r = [], o = {}, l = arr2.length, i, v;
                for (i = 0; i < l; i++) {
                    o[arr2[i]] = true;
                }
                l = arr1.length;
                for (i = 0; i < l; i++) {
                    v = arr1[i];
                    if (v in o) {
                        r.push(v);
                    }
                }
                return r;
            }
            
            function changeFilter(newFilter, context) {
                if (useRoutes) {
                    router.go(newFilter.updateLocation(router.location()),
                        context);
                } else {
                    resource.setIndexFilter(newFilter);
                    getIndexResults();
                }
            }
            
            function taskHandlers(handlers){
            	
            	return {
                    success: function (data) {
                    	var i,resources=[];
                    	if(data.hapi.tasks.task.length != 0)
	                    	{
	                    		for(i = 0; i < data.hapi.tasks.task.length; i += 1)
	                    		{
	                    			var item={
                                                category: 'task',
                                                collapse: 'collapse',
                                                status:  data.hapi.tasks.task[i].task_criticality,
                                                Resource: data.hapi.tasks.task[i].task_resource,
                                                Message: data.hapi.tasks.task[i].task_status,
                                                state: data.hapi.tasks.task[i].task_state,
                                                LastUpdate: data.hapi.tasks.task[i].task_datetime,
												taskid: data.hapi.tasks.task[i].task_id,
		                    		};
		                    		resources =resources.concat(item);
	                    		}
	                    		var members = resources;
			                    var indexResults = {count: members.length,
			                        members: members, total: resources.length};
			             
	                        	handlers.success(indexResults);
	                       }
	                       else {
		                       	var indexResults = {count: 0,
				                        members: [], total: 0};
		                       	handlers.success(indexResults);
	                       }
                    },
                    error: handlers.error};                   
            }
            
            /**
             * @public
             */
            this.init = function() {
                if (! initialized) {
                    initialized = true;
                    resource.on("indexResultsChange", onIndexResultsChange);
                    resource.on("selectionChange", onSelectionChange);
                    resource.on("filterChange", onFilterChange);
                }
            };
            
            this.pause = function () {
                clearInterval(timer);
            };
            
            this.resume = function (useRoutesArg) {
                useRoutes = useRoutesArg;
                /*if (settings.getRefreshInterval()) {
                    timer = setInterval(getIndexResults,
                        settings.getRefreshInterval());
                }*/
            };
            
            this.renotify = function (sendResults) {
                resource.renotify(sendResults);
            };
            
            this.getIndexResults = getIndexResults;
            
            this.haveItems = function () {
                return resource.haveSome();
            };
            
            this.addItem = function (item, handlers) {
                resource.addItem(item, handlers);
            };
            
            this.getItem = function(uri) {
                return resource.getItem(uri);
            };
            
            this.updateSelectedItems = function (item, handlers) {
                resource.updateItems(resource.getSelection().uris, item, handlers);
            };
            
            this.clearSelectedItems = function () {
                $.each(resource.getSelection().uris, function (index, uri) {
                    var item = resource.getIndexResultForUri(uri);
                    if ('alert' === item.category) {
                        item.state = 'cleared';
                    }
                });
                resource.renotify(true);
            };
            
            this.deleteSelectedItems = function (handlers) {
                indexService.deleteItems(resource.getSelection().uris);
                resource.clearAllSelectedUris();
                resource.renotify(true);
            };
            
            this.getStateFilter = function (global) {
                var filter = resource.getIndexFilter();
                var statuses = null;
                var states = null;
                var owner = null;
                var result = [];
                
                if (filter) {
                    statuses = filter.getProperty('status');
                    states = filter.getProperty('state');
                    owner = filter.getProperty('owner');
                }
                
                if (statuses) {
                    result = result.concat(statuses);
                }
                if (states) {
                    result = result.concat(states);
                }
                if (owner) {
                    result.push('Mine');
                }
                return result;
            };
            
            this.getStateFilterSummary = function(global) {
                var values = this.getStateFilter();
                var result = values.join(', ');
                if (result ===
                    ([]).concat(global ? DEFAULT_GLOBAL_STATUSES :
                        DEFAULT_RESOURCE_STATUSES).concat(DEFAULT_STATES).
                        join(', ')) {
                    result = (global ? 'Active issues' : 'Active');
                } else if (result.length === 0) {
                    result = 'All states';
                }
                return result;
            };
            
            this.setStateFilter = function (values, global) {
                if (! $.isArray(values)) {
                    values = [values];
                }
                var newFilter = new IndexFilter(resource.getIndexFilter());
                
                var states = getIntersect(values, STATES);
                if (0 !== states.length && ! areSame(states, STATES)) {
                    newFilter.setProperty('state', states);
                } else {
                    newFilter.unsetProperty('state');
                }
                
                var statuses = getIntersect(values, STATUSES);
                if (0 !== statuses.length && ! areSame(statuses, STATUSES)) {
                    newFilter.setProperty('status', statuses);
                } else {
                    newFilter.unsetProperty('status');
                }
                
                if ($.inArray('Mine', values) !== -1) {
                    newFilter.setProperty('owner', session.getUser());
                } else {
                    newFilter.unsetProperty('owner');
                }
                
                changeFilter(newFilter, "activity filter change");
            };
            
            this.setDefaultFilters = function (global) {
                var newFilter = new IndexFilter(resource.getIndexFilter());
                newFilter.setProperty('status', (global ? DEFAULT_GLOBAL_STATUSES :
                    DEFAULT_RESOURCE_STATUSES));
                newFilter.setProperty('state', DEFAULT_STATES);
                newFilter.unsetProperty('category');
                newFilter.unsetProperty('owner');
                
                changeFilter(newFilter, "activity default filter change");
            };
            
            this.setFilterSearch = function(query) {
                var newFilter = new IndexFilter(resource.getFilter());
                newFilter.setUserQuery(query);
                changeFilter(newFilter, "activity search change");
            };
            
            this.getCategoryFilter = function () {
                var filter = resource.getIndexFilter();
                var result = DEFAULT_CATEGORY;
                if (filter) {
                    result = filter.getProperty('category');
                    result = (result ? result : DEFAULT_CATEGORY);
                }
                return result;
            };
            
            this.setCategoryFilter = function (value) {
                var newFilter = new IndexFilter(resource.getIndexFilter());
                if (value && 'all' !== value) {
                    newFilter.setProperty('category', value);
                } else {
                    newFilter.unsetProperty('category');
                }
                changeFilter(newFilter, "activity category filter change");
            };
            
            this.getSourceUris = function () {
                var filter= resource.getIndexFilter();
                return filter.getProperty('sourceUri');
            };
            
            this.setSourceUris = function (uris) {
                var newFilter = new IndexFilter(resource.getIndexFilter());
                newFilter.setProperty('sourceUri', uris);
                //if (resource.setIndexFilter(newFilter)) {
                  //getIndexResults();
                //}
                resource.setIndexFilter(newFilter);
                setTimeout(getIndexResults, 10);
            };
            
            this.getSelection = function() {
                return resource.getSelection();
            };
            
            this.isSelectedUri = function(uriArg) {
                var result = false;
                $.each(resource.getSelection().uris, function (index, uri) {
                    if (uri === uriArg) result = true;
                });
                return result;
            };
            
            this.toggleSelectedUri = function(uriArg, clear) {
                var uris = $.grep(resource.getSelection().uris, function (uri) {
                    return (uriArg !== uri);
                });
                if (uris.length === resource.getSelection().uris.length) {
                    // wasn't already selected
                    if (clear) {
                        uris = [uriArg];
                    } else {
                        uris.push(uriArg);
                    }
                } else {
                    if (clear) uris = [];
                }
                resource.setSelectedUris(uris);
            };
            
            this.setSelectedUris = function(uris) {
                resource.setSelectedUris(uris);
            };
            
            this.selectAll = function() {
                resource.selectAll();
            };
            
            this.removeSelectedUri = function(uri) {
                var uris = resource.getSelection().uris;
                resource.setSelectedUris($.grep(uris, function(elem, index) {
                    return elem !== uri;
                }));
            };
            
            this.addNote = function(uri, note) {
                var alert = resource.getIndexResultForUri(uri);
                alert.notes.push(note);
                resource.renotify(true);
            };
            
            this.getRouteContext = function () {
                return urlFragment.getPage(router.location());
            };
            
            this.getTaskData = function (handlers) {
				
				var uri = '/Session/' + session.getToken() + '/gettaskdata';
           	 	REST.postObject(uri, 
								{
				 			 hapi: {
				    	filters: {
				      	range: {
				        index: 1,
				        count: 501
				      }
				    }
				  }
				},  "", taskHandlers(handlers), {});
			};
            
            /**
             * Add a listener for a specified event.
             * @public
             * @param {string} eventName The name of the event.
             * @param {function(...)}
             */
            this.on = function(eventName, callback) {
                dispatcher.on(eventName, callback);
            };
            
            this.off = function(eventName, callback) {
                dispatcher.off(eventName, callback);
            };
        }

        return ActivityPresenter;
    }());

    return ActivityPresenter;
});
