// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(['hp/services/REST', 'hp/services/IndexFilter',
        'hp/services/IndexThrottler', 'hp/services/Log', 'hp/model/Session', 'jquery','hpsum/common/utility'],
function(REST, IndexFilter, IndexThrottler, log, session) { "use strict";

    var IndexService = (function() {

        var URL_PREFIXES = {
            1: '/index/rest/index',
            // 2 is required for richer filtering
            2: '/rest/index',
            // 3 is required to support referenceUri for trees, associations and resource
            3: '/rest/index'
        };

		var SUCCESS = 0;
        var URI_PROP_NAME = 'uri';
        function IndexService() {
          
          	var version = 1;
		var locations = [];
		var urlPrefix = URL_PREFIXES[1];
          	var resources = [];
          	var index, iterator;
		var NODE_INSTALLABLE_STATUS_UPDATE_REQ = 0;
          	
		// TODO We are not able to recall why we need this method. Should
		// remove this eventually.
            function convertResource(resource) {
                if (resource.hasOwnProperty('displayName')) {
                    resource.name = resource.displayName;
                    resource.status = resource.healthStatus;
                    resource.state = resource.resourceState;
                    delete resource.displayName;
                    delete resource.healthStatus;
                    delete resource.resourceState;
                }
            }
          
            function convertIndexResources(indexResources) {
                if (indexResources.hasOwnProperty('resources')) {
                    indexResources.members = indexResources.resources;
                    delete indexResources.resources;
                    // convert properties
                    $.each(indexResources.members, function (index, resource) {
                        convertResource(resource);
                    });
                    
                    indexResources.count = indexResources.totalIndexResources;
                    delete indexResources.totalIndexResources;
                }
            }
            
            function indexResourcesHandlers(filter,handlers) {
                return {
                    success: function (data) {
                    	var index_outer,resources=[];
                    	
					 if (filter.data.category == 'group') {
					 
							if((filter.data.sort=="name:desc")||(filter.data.sort=="status:desc")){
							 for(index_outer = 0; index_outer < data.hapi.output_data.groups.group.length; index_outer += 1){
							  for(var index_inner = index_outer+1; index_inner < data.hapi.output_data.groups.group.length; index_inner += 1)
								{
									if (data.hapi.output_data.groups.group[index_outer].group_name < data.hapi.output_data.groups.group[index_inner].group_name){				              			              
										var swapping = data.hapi.output_data.groups.group[index_inner];				   
										data.hapi.output_data.groups.group[index_inner] = data.hapi.output_data.groups.group[index_outer];
										data.hapi.output_data.groups.group[index_outer] = swapping;	
									}
								}
							 }
							}
							else{
							 for(index_outer = 0; index_outer < data.hapi.output_data.groups.group.length; index_outer += 1){
							  for(var index_inner = index_outer+1; index_inner < data.hapi.output_data.groups.group.length; index_inner += 1)
								{
									if (data.hapi.output_data.groups.group[index_outer].group_name > data.hapi.output_data.groups.group[index_inner].group_name){				              			              
										var swapping = data.hapi.output_data.groups.group[index_inner];				   
										data.hapi.output_data.groups.group[index_inner] = data.hapi.output_data.groups.group[index_outer];
										data.hapi.output_data.groups.group[index_outer] = swapping;	
									}
								}
							 }
							}
					 
					 		if (data.hapi.output_data.groups.group.length != 0) {
									for ( index_outer = 0; index_outer < data.hapi.output_data.groups.group.length; ++index_outer) {
										var group = data.hapi.output_data.groups.group[index_outer],
										    change = false,
										    groupState = group.group_state,
										    groupPhase = group.group_phase,
											group_inst_code = group.group_installable_code,
										    status;

										if (groupState.match(/INSTALLDONE/i) || groupPhase.match(/NoComponents/i)) {
											if (group.group_return_code < SUCCESS) {											
												status = 'error';
											}
											else {
												status = 'ok';
											}
										} else if (groupState.match(/IDLE/i)){
											status = 'warning';
										}
										else if(groupState.match(/SCHEDULED/i)) {
											status = 'scheduled';
										}
										else if (groupPhase.match(/Initialize/i) ||
										    groupState.match(/INVENTORY|SELFINVENTORY|ANALYSIS|INSTALL/)) {
											status = 'running';
											change = true;
										} else if (groupPhase.match(/InActive|Error/i)) {
											status = 'error';
										} else if (group_inst_code == NODE_INSTALLABLE_STATUS_UPDATE_REQ){ 
											status = 'warning';
										} else {
											status = 'ok';
										}
										
										var item = {
											name : group.group_name,
											group_name: group.group_name,
											description : group.group_description,
											group_description: group.group_description,
											group_id : group.group_id,
											group_state : group.group_state,
											group_phase : group.group_phase,
											group_status : group.group_status,
											group_nodes : group.group_nodes,
											uri : '/session/' + session.getToken() + '/node/group/' + group.group_id + '/getdata',
											changing : change,
											status : status,
											stateDetails : '',
											index : index_outer,
										};

										resources = resources.concat(item);

									}
									var members = resources;
									var indexResults = {
										count : members.length,
										members : members,
										total : resources.length,
										filter : filter
									};
									handlers.success(indexResults);
								}
								else {
									var indexResults = {count: 0,
											members: [], total: 0, filter: filter};
									handlers.success(indexResults);
								}
					 }
					 else if (filter.data.category == 'ilofederation') {
						 if((filter.data.sort=="name:desc")||(filter.data.sort=="status:desc")){
							 for(index_outer = 0; index_outer < data.hapi.output_data.scalable_groups.scalable_group.length; index_outer += 1){
							  for(var index_inner = index_outer+1; index_inner < data.hapi.output_data.scalable_groups.scalable_group.length; index_inner += 1)
								{
									if (data.hapi.output_data.scalable_groups.scalable_group[index_outer].sug_name < data.hapi.output_data.scalable_groups.scalable_group[index_inner].sug_name){				              			              
										var swapping = data.hapi.output_data.scalable_groups.scalable_group[index_inner];				   
										data.hapi.output_data.scalable_groups.scalable_group[index_inner] = data.hapi.output_data.scalable_groups.scalable_group[index_outer];
										data.hapi.output_data.scalable_groups.scalable_group[index_outer] = swapping;	
									}
								}
							 }
							}
							else{
							 for(index_outer = 0; index_outer < data.hapi.output_data.scalable_groups.scalable_group.length; index_outer += 1){
							  for(var index_inner = index_outer+1; index_inner < data.hapi.output_data.scalable_groups.scalable_group.length; index_inner += 1)
								{
									if (data.hapi.output_data.scalable_groups.scalable_group[index_outer].sug_name > data.hapi.output_data.scalable_groups.scalable_group[index_inner].sug_name){				              
										var swapping = data.hapi.output_data.scalable_groups.scalable_group[index_inner];				   
										data.hapi.output_data.scalable_groups.scalable_group[index_inner] = data.hapi.output_data.scalable_groups.scalable_group[index_outer];
										data.hapi.output_data.scalable_groups.scalable_group[index_outer] = swapping;	
									}
								}
							 }
							}
					 
					 		if (data.hapi.output_data.scalable_groups.scalable_group.length != 0) {
									for ( var index = 0; index < data.hapi.output_data.scalable_groups.scalable_group.length; ++index) {
										var group = data.hapi.output_data.scalable_groups.scalable_group[index],
										    change = false,
										    groupState = group.sug_state,
										    groupPhase = group.sug_status,
										    status;
										    
										
										if (groupState.match(/INSTALLDONE/i) || groupPhase.match(/NoComponents/i)) {
											if (group.group_return_code < SUCCESS) {											
												status = 'error';
											}
											else {
												status = 'ok';
											}
										} else if (groupPhase.match(/Initialize/i) ||
										    groupState.match(/INVENTORY|SELFINVENTORY|ANALYSIS|INSTALL|Adding_interface_ilo/i)) {
											status = 'running';
											change = true;
										} else if (groupState.match(/Error/i)) {
											status = 'error';
										} else if(groupState.match(/Not_on_network/i)){
											status = 'error';
										}else {
											status = 'warning';
										}
										
										var item={
			                    		 	type: group.sug_name,
			                        		name: group.sug_name,
			                        		uri:  group.sug_uri+'/getdata', 
			                       	 		sug_state: group.sug_state, 
			                       	 		sug_status: group.sug_status,
			                        		changing: change,
			                        		status : status,
			                        		stateDetails: '',
			                        		index: index,
			                    		};

										resources = resources.concat(item);

									}
									var members = resources;
									var indexResults = {
										count : members.length,
										members : members,
										total : resources.length,
										filter : filter
									};
									handlers.success(indexResults);
								}
								else {
									var indexResults = {count: 0,
											members: [], total: 0, filter: filter};
									handlers.success(indexResults);
								}
					 }
                     else if(filter.data.category == 'node') {
                        if((filter.data.sort=="name:desc")||(filter.data.sort=="status:desc")){
							data.hapi.output_data.nodes.node = sortNodes(data.hapi.output_data.nodes.node, 'desc','sortedData');
 		                 }
			            else{
		                 data.hapi.output_data.nodes.node = sortNodes(data.hapi.output_data.nodes.node, 'asc','sortedData');
 		                }
                      if (data.hapi.output_data.nodes.node.length != 0)
                    	{
                    		for(index_outer = 0; index_outer < data.hapi.output_data.nodes.node.length; index_outer += 1)
                    		{
                    			var change = false;
                    			var status = 'unknown';
                    			if(data.hapi.output_data.nodes.node[index_outer].node_state.match(/inventory|install$|ILO_TASK_INPROGRESS|INSTALLFROMILOTASKQUEUE|INSTALLFROMRECOVERYSET/i) || 
									data.hapi.output_data.nodes.node[index_outer].node_phase.match(/initialize/i) ||
									data.hapi.output_data.nodes.node[index_outer].node_phase.match("REMOTE_STAGING_UAN"))
								{
                    				change = true;
                    				status = 'unknown';
                    			}
                    			else 
                    				change = false;
                    			
                    			if(data.hapi.output_data.nodes.node[index_outer].node_state.match(/error/i))
                    				status = 'error';
                    			else if(data.hapi.output_data.nodes.node[index_outer].node_state.match(/uan/i)){
									if(data.hapi.output_data.nodes.node[index_outer].installable_state == NODE_INSTALLABLE_STATUS_UPDATE_REQ)                    				
                    					status = 'warning';
                    				else
                    					status = 'ok';	
                    			} else if(data.hapi.output_data.nodes.node[index_outer].node_state.match(/installdone/i) &&
										 !data.hapi.output_data.nodes.node[index_outer].node_phase.match(/initialize/i) ) {
										if (data.hapi.output_data.nodes.node[index_outer].return_code < SUCCESS) {                    					
                    					    status = 'error';
                    					} else {
                    					    status = 'ok';
                    					}
                    			}
                    			else if(data.hapi.output_data.nodes.node[index_outer].node_state.match(/idle/i)) {
                    					if(data.hapi.output_data.nodes.node[index_outer].node_phase.match(/unknown|error/i))
                    						status = 'error';
                    					else
                    						status = 'warning';
                    			}
                    			else if(data.hapi.output_data.nodes.node[index_outer].node_state.match(/scheduled$/i)){
                    				status = 'scheduled';
                    			}
                    			
                    			
                  			var item={
                    		 	type: displayILO(data.hapi.output_data.nodes.node[index_outer].type),
                        		name: data.hapi.output_data.nodes.node[index_outer].node_name,
                        		uri:  data.hapi.output_data.nodes.node[index_outer].node_uri+'/getdata', //'/' + 'baseline' + '/item',
                       	 		node_state: data.hapi.output_data.nodes.node[index_outer].node_state, //'ok',
                       	 		node_phase: data.hapi.output_data.nodes.node[index_outer].node_phase,
                       	 		node_status:  data.hapi.output_data.nodes.node[index_outer].node_status,
                        		changing: change,
                        		status : status,
                        		stateDetails: '',
                        		index: index_outer,
                                attributes : {
                                            hidden : true
                                        }
                    		};
                    		resources =resources.concat(item);
                    		}
                    		var members = resources;
		                    var indexResults = {count: members.length,
		                        members: members, total: resources.length, filter: filter};
		             
                        handlers.success(indexResults);
                        }
                      
                       else {
                       	var indexResults = {count: 0,
		                        members: [], total: 0, filter: filter};
                       	handlers.success(indexResults);
                       }
                       }
                    },
                    error: function() {
                        if(handlers) {
                            handlers.error();
                        }
                    }
                };
            }
            
						
            function indexLocations(filter, handlers, parenthandlers) {
            	
            	var baselinesHandlers = {
                        success: function (data) {
                            onGetBaselinesSuccess(data, parenthandlers, filter);
                        },
                        error: function (errorInfo) {
                            onGetBaselinesError(errorInfo);
                        }
                    };
                    
                return {
                    success: function (data) {
                    	var i, uri;
						var inv_finished = false;
                    	iterator = 0;
                    	resources = [];
                    	locations = [];
 

							if (data.hapi.hasOwnProperty("output_data")) {
								var baselines = [], locationURI, indexLocations = [], locationInfo, change, baselineInfo;
								indexLocations = data.hapi.output_data.locations.location;

								//Process all locations information
								for (var idx = 0; idx < indexLocations.length; idx++) {
									if(indexLocations[idx].location_type.match(/FTP/i) || indexLocations[idx].location_type.match(/HTTP/i))
										locationURI = indexLocations[idx].working_location;
									else
										locationURI = indexLocations[idx].location_uri;
									locationInfo = {
										location_id : indexLocations[idx].locationid,
										location_uri : locationURI,
										location_name : indexLocations[idx].location_name
									};
									
									baselines = baselines.concat(indexLocations[idx].baselines.baseline);
									
									if(indexLocations[idx].baselines.baseline.length>0)
									locations = locations.concat(locationInfo);
								}

								//Process all baselines information associated with the all locations
								var inv_in_progress = false;
								for (var idx = 0; idx < baselines.length; idx++) {
									change = 0;
									if (baselines[idx].baseline_state.match(/abort_in_progress|inventory_in_progress|inventory_web_catalog_downloading|comp_download_in_progress|reading_web_catalog|reading_manifest_xml|manifest_component_processing/i)) {
										change = 1;
										inv_in_progress =true;
									}
									if(baselines[idx].location_type.match(/FTP/i) && baselines[idx].baseline_state.match(/abort_completed/i))
										continue;
									baselineInfo = {
										category : 'baseline',
										name : baselines[idx].baseline_name,
										id: baselines[idx].baseline_id,
										location : baselines[idx].baseline_url,
										uri : baselines[idx].baseline_uri + '/getBaselineData',
										state : baselines[idx].baseline_state,
										location_type : baselines[idx].location_type,
										changing : change,
										updatedAt : baselines[idx].baseline_updated_at,
										stateDetails : '',
										associated_node_count: baselines[idx].nodes_using_baseline,
										location_id : baselines[idx].locationid,
										index : resources.length,
										attributes : {
											version : baselines[idx].baseline_version //,
											//size : baselines[idx].baseline_size
										}
									};
									if(baselineInfo.state == "inventory_completed")
									{
										inv_finished = true;
									}
									resources = resources.concat(baselineInfo);
								}

								if (resources) {

									var regexps = [];
									if (filter.data.terms) {
										regexps = $.map(filter.data.terms, function(term) {
											return new RegExp(term, 'i');
										});
									}
									resources = $.grep(resources, function(item, index) {
										var match = true;

										if (filter.data.properties) {

											$.each(filter.data.properties, function(property, value) {
												if (!item[property]) {
													match = false;
												} else {
													if ('array' === $.type(value)) {
														if (-1 === $.inArray(item[property], value)) {
															match = false;
														}
													} else {
														if (value && value.toLowerCase() !== item[property].toLowerCase()) {
															match = false;
														}
													}
												}
											});
										}

										if (match) {
											$.each(regexps, function(index, regexp) {
												if (! item.name.match(regexp) && (!item.sourceName || ! item.sourceName.match(regexp)) && (!item.owner || ! item.owner.match(regexp))) {
													match = false;
													return false;
												}
											});
										}
										return match;
									});

									var members = resources;
									var indexResults = {
										count : members.length,
										members : members,
										total : resources.length,
										filter : filter,
										category : 'baseline',
										inv_finished : inv_finished,
										inv_in_progress : inv_in_progress
									};
									if (parenthandlers && parenthandlers.success) {
										parenthandlers.success(indexResults);
									}
								} else {
									if (handlers && handlers.error) {
										handlers.error('No items for baselines');
									}
								}
							}    


                    	else
                    	{
                    		var members = resources;
		                    var indexResults = {count: members.length,
		                        members: members, total: resources.length, filter: filter};
		                    if (parenthandlers && parenthandlers.success) {
		                        parenthandlers.success(indexResults);
		                    }
                    	}            		
                    },
                    error: handlers.error};
            }
            
            function convertTree(tree) {
                convertResource(tree.resource);
                $.each(tree.parents, function (assoc, parents) {
                    $.each(parents, function (index, parent) {
                        convertTree(parent);
                    });
                });
                $.each(tree.children, function (assoc, children) {
                    $.each(children, function (index, child) {
                        convertTree(child);
                    });
                });
            }
            
            function convertTrees(trees) {
                if (trees.hasOwnProperty('trees')) {
                    $.each(trees.trees, function (index, tree) {
                        convertTree(tree);
                    });
                } else {
                    convertTree(trees);
                }
            }
            
            function treesHandlers(handlers) {
                return {
                    success: function (data) {
                        convertTrees(data);
                        handlers.success(data);
                    },
                    error: handlers.error};
            }
            
            function serializeCategory(category) {
                var result;
                if ('array' === $.type(category)) {
                    result = $.map(category, function (cat, index) {
                        return 'category=' + cat;
                    }).join('&');
                } else {
                    result = 'category=' + category;
                }
                return result;
            }
            
            function onGetLocationsSuccess(data, handlers)
            {
            	//locations = data;
            	handlers.success(resources);
            }
            
            function onGetLocationsError(data)
            {
            	locations = {};
            }
            
            function onGetBaselinesSuccess(data, handlers, filter)
            {
            	var i;
            	//Create resources out of the data received as response
            	for(i = 0; i < data.hapi.output_data.baselines.baseline.length; i += 1)
            	{
            		var change = 0;
        			if(data.hapi.output_data.baselines.baseline[i].baseline_state.match(/inventory_in_progress|inventory_web_catalog_downloading|comp_download_in_progress|reading_web_catalog|reading_manifest_xml|manifest_component_processing/i))
        				change =1;
        				
            		var item = {
                        category: 'baseline',
                        name: data.hapi.output_data.baselines.baseline[i].baseline_name,
                        location: data.hapi.output_data.baselines.baseline[i].baseline_url,
                        uri: data.hapi.output_data.baselines.baseline[i].baseline_uri+ '/index', //'/' + 'baseline' + '/item',
                        state: data.hapi.output_data.baselines.baseline[i].baseline_state, //'ok',
                        location_type: data.hapi.output_data.baselines.baseline[i].location_type, 
                        changing: change,
                        updatedAt: data.hapi.output_data.baselines.baseline[i].baseline_updated_at,
                        stateDetails: '',
                        index: resources.length,
			associated_node_count: data.hapi.output_data.baselines.baseline[i].nodes_using_baseline,
                        attributes: {version: data.hapi.output_data.baselines.baseline[i].baseline_version} //, size: data.hapi.output_data.baselines.baseline[i].baseline_size}
                   	};
            		
            		resources = resources.concat(item);
            	}
            	
            	iterator -= 1;
            	
            	if(iterator == 0)
            	{
            		if (resources) {
           			
            			var regexps = [];
		                if (filter.data.terms) {
		                    regexps = $.map(filter.data.terms, function (term) {
		                        return new RegExp(term, 'i');
		                    });
		                }
		                resources = $.grep(resources,
		                    function(item, index) {
		                    var match = true;
		                    
		                    if (filter.data.properties) {
		                        
		                        $.each(filter.data.properties, function (property, value) {
		                            if (! item[property]) {
		                                match = false;
		                            } else {
		                                if ('array' === $.type(value)) {
		                                    if (-1 === $.inArray(item[property], value)) {
		                                        match = false;
		                                    }
		                                } else {
		                                    if (value &&
		                                        value.toLowerCase() !==
		                                            item[property].toLowerCase()) {
		                                        match = false;
		                                    }
		                                }
		                            }
		                        });
		                    }
		                    
		                    if (match) {
		                        $.each(regexps, function (index, regexp) {
		                            if (! item.name.match(regexp) &&
		                                (! item.sourceName || ! item.sourceName.match(regexp)) &&
		                                (! item.owner || ! item.owner.match(regexp))) {
		                                match = false;
		                                return false;
		                            }
		                        });
		                    }
		                    return match;
		                });
		                
	                    var members = resources;
	                    var indexResults = {count: members.length,
	                        members: members, total: resources.length, filter: filter};
	                    if (handlers && handlers.success) {
	                        handlers.success(indexResults);
	                    }
	                } else {
	                    if (handlers && handlers.error) {
	                        handlers.error('No items for baselines');
	                    }
	                }
                	
            	}
            }
            
            function onGetBaselinesError(data)
            {
            	//locations = {};
            }
            	    
	    function hasUriArrayInFilter(filter) {
                return filter.data && filter.data.properties &&
                    filter.data.properties[URI_PROP_NAME] &&
                    $.isArray(filter.data.properties[URI_PROP_NAME]);
            }

            //used for Tasks List
            function taskHandlers(filter, 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, filter: filter};
			             
	                        	handlers.success(indexResults);
	                       }
	                       else {
		                       	var indexResults = {count: 0,
				                        members: [], total: 0, filter: filter};
		                       	handlers.success(indexResults);
	                       }
                    },
                    error: handlers.error};                   
                
            }
            
            this.getLocations = function (){
            	return locations;
            };

            // TODO make a new method here that will take the new argument (associationNames)
            this.getIndexResources = function (category, start, count, handlers) {
                
                REST.getURI('/index/rest/index/resources?' +
                    serializeCategory(category) +
                    '&start=' + start + '&count=' + count + '&sort=name:asc',
                    indexResourcesHandlers(handlers));
            };
        
            this.getFilteredIndexResources = function (filter, handlers) {
                //var uri = '/index/rest/index/resources?';
                 if ('array' === $.type(filter.data.category)) 
                 filter.data.category = 'node';
                var uri = '/Session/' + session.getToken() + '/' + filter.data.category;
                var params = [];
                var filterData = filter.data;
                if (! filterData) {
                    log.warn('Reverting to deprecated filter in IndexService.' +
                        ' Convert caller to use IndexFilter.');
                    filterData = filter;
                }
                $.each(filterData, function (name, value) {
                    if ('properties' === name) {
                        $.each(value, function (property, propertyValue) {
                            if ('array' === $.type(propertyValue)) {
                                $.each(propertyValue, function (index, val) {
                                    params.push('filter=' + property + ':' + val);
                                });
                            } else {
                                params.push('filter=' + property + ':' + propertyValue);
                            }
                        });
                    } else if ('terms' === name) {
                        if (value.length > 0) {
                            var tval=[];
                            // if the value contains white space, add double quotes
                            $.each(value, function (index, val) {
                                tval.push((/\s/g.test(val)) ? '"' + val + '"' : val);
                            });
                            params.push('userQuery=' + tval.join(' '));
                        }
                    } else if ('userQuery' !== name) {
                        if ('array' === $.type(value)) {
                            $.each(value, function (index, val) {
                                params.push(name + '=' + val);
                            });
                        } else {
                            params.push(name + '=' + value);
                        }
                    }
                });
                uri += params.join('&');
                
                //If this request for baseline, then get the locations first then get baselines based on location id 
                if(filter.data.category == 'baseline')
                {
                	var locHandlers = {
                        success: function (data, handlers) {
                            onGetLocationsSuccess(data);
                        },
                        error: function (errorInfo) {
                            onGetLocationsError(errorInfo);
                        }
                    };
                	
                	//Get all the locations along with their baselines associated with them at one shot
                	uri = '/Session/' + session.getToken() + '/' + filter.data.category + '/location/index?indexChilds=Yes';
                	REST.getURI(uri, indexLocations(filter, locHandlers, handlers));
                }
                else if(filter.data.category === 'task') {
                	uri = '/Session/' + session.getToken() + '/gettaskdata';
               	 	REST.postObject(uri, 
									{
					 			 hapi: {
					    	filters: {
					      	range: {
					        index: 1,
					        count: 501
					      }
					    }
					  }
					},  "", taskHandlers(filter, handlers), {}); 
                }
                else if(filter.data.category == 'group') {
                	uri = '/session/' + session.getToken() + '/node/group/index';
                	REST.getURI(uri, indexResourcesHandlers(filter, handlers));
                }
                else if(filter.data.category == 'ilofederation') {
                	uri = '/session/' + session.getToken() + '/node/ScalableUpdate/index';
                	REST.getURI(uri, indexResourcesHandlers(filter, handlers));
                }
                else
                {
                	//for other resources like node, session etc
                	uri = '/Session/' + session.getToken() + '/' + filter.data.category + '/index';
                	if(filter.data.userQuery != undefined)
                		uri+='?filter=' + filter.data.userQuery;
                
               	 	REST.getURI(uri, indexResourcesHandlers(filter,handlers));
               	}
            };

            this.getAssociationTree = function (uriArg, depth, handlers) {
                var uri = urlPrefix + '/associationtree?rootUri=' + uriArg +
                    '&depth=' + depth;
                REST.getURI(uri, handlers, {apiVersion: version});
            };

            this.searchIndexResources = function (filter, start, count, handlers) {
                if ('string' === typeof(filter)) {
                    var realFilter = new IndexFilter();
                    realFilter.setUserQuery(filter);
                    filter = realFilter;
                }
                var query = '';
                if (filter.data.terms) {
                    query = filter.data.terms.join(' ');
                }
                var uri = urlPrefix + '/resources?userQuery=' +
                    encodeURIComponent(query) +
                    '&start=' + start + '&count=' + count;
                REST.getURI(uri, indexResourcesHandlers(handlers), {apiVersion: version});
            };

            this.suggestions = function(category, query, start, count, handlers) {
                var uri = urlPrefix + '/' +
                    (1 === version ? 'suggestions' : 'search-suggestions') + '?';
                if (category) {
                    uri += serializeCategory(category) + '&';
                }
                uri += 'userQuery=' + encodeURIComponent(query) +
                    '&start=' + start + '&count=' + count;
                REST.getURI(uri, handlers, {apiVersion: version});
            };

            this.getAssociationTrees = function (category, depth, associationNames,
                start, count, handlers) {
                var uri = urlPrefix + '/associationtrees?'+
                    serializeCategory(category) +
                    '&depth=' + depth+
                    '&associationNames='+associationNames+
                    '&start=' + start+
                    '&count=' + count;
                REST.getURI(uri, handlers, {apiVersion: version});
            };

            this.getIndexForResource = function (uri, handlers) {
                REST.getURI('/index/rest/index/resources?start=0&count=1&filter=_uri:' +
                    uri, handlers);
            };

            /**
             * Retrieves the associations from the index service
             * @param {string} startObjUri - The starting object uri (optionally null)
             * to look at when getting associations.
             * @param {string} endObjUri - The ending object uri (optionally null)
             * to look at when getting associations.
             * @param {string} associationName - One of a set association names
             * (optionally null).
             * @param {string} relationship - Boolean value (optionally null).
             * @param {object} handlers - Success and Error handlers.
             */
            this.getAssociations = function (startObjUri, endObjUri, associationName,
                relationship, handlers) {
                var params = [];
                if (startObjUri) {
                    params.push("startObjUri=" + startObjUri);
                }
                if (endObjUri) {
                    params.push("endObjUri=" + endObjUri);
                }
                if (associationName) {
                    params.push("associationName=" + associationName);
                }
                if (relationship) {
                    params.push("hasARelationship=" + relationship);
                }
                var request = "/index/rest/index/associations?" + params.join('&');
                REST.getURI(request, handlers);
            };

            /**
             * Retrieves the parent and children associations from the index service
             * @param {object} Options object telling parameters to set in REST call.
             * Not used if not set.
             *   Supported params (Pass either uri or catagory, but not both)
             *
             *     uri = Uri of item to retrieve. Retrieves single item specified by Uri.
             *
             *     catagory = What type of object to get. {servers,enclosure,...}.
             *                Fetches a range of objects of this type.
             *       start = Which item to start with (For use with catagory)
             *       count = How many items to fetch (For use with catagory)
             *
             *     childDepth = Descent depth for following child associations. (Always valid)
             *     parentDepth = Descent depth for following parent associations. (Always valid)
             *     handlers = object w/ success/error handlers (Always)
             */
            this.getParentAndChildrenAssociations = function (options) {
                var params = [];
                var handlers = null;
                var uri = "";

                if(arguments.length == 1) {
                    // New version, parsing an Option object
                    uri = ((options.uri) ? options.uri : "");
                    if (options.category) {
                        if ('array' === $.type(options.category)) {
                            $.each(options.category, function (index, cat) {
                                params.push("category=" + cat);
                            });
                        } else {
                            params.push("category=" + options.category);
                        }
                    }
                    if (options.childDepth) {
                        params.push("childDepth=" + options.childDepth);
                    }
                    if (options.parentDepth) {
                        params.push("parentDepth=" + options.parentDepth);
                    }
                    if (options.start) {
                        params.push("start=" + options.start);
                    }
                    if (options.count) {
                        params.push("count=" + options.count);
                    }
                    if (options.sort) {
                        params.push("sort=" + options.sort);
                    }
                    if (options.handlers) {
                        handlers = options.handlers;
                    }
                } else {
                    // Old version which took multiple arguments
                    uri = arguments[0];
                    var childDepth = arguments[1];
                    var parentDepth = arguments[2];
                    handlers = arguments[3];
                
                    if (childDepth) {
                        params.push("childDepth=" + childDepth);
                    }
                    if (parentDepth) {
                        params.push("parentDepth=" + parentDepth);
                    }
                }
                REST.getURI("/index/rest/trees" + uri + "?" + params.join('&'),
                    treesHandlers(handlers));
            };
            this.checkForExistence = function (filter, handlers) {
                var throttler;
                if (hasUriArrayInFilter(filter)) {
                    throttler = new IndexThrottler();
                    throttler.init({
                        urlPrefix: urlPrefix,
                        version: version,
                        filter: filter,
                        handlers: handlers
                     });
                     throttler.getFilteredUris();
                } else {
                    log.warn('The uri property is not set before checking for its existence.');
                }
            };
            this.version = function () {
                return version;
            };
        }
        return new IndexService();
    }());
    
    return IndexService;
});
