// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
/**
 * @type {GroupPresenter}
 */
define(['hpsum/model/group/GroupResource',
    'hpsum/presenter/baseline/BaselinePresenter',
    'hpsum/presenter/node/NodePresenter',
    'hp/services/IndexService',
    'hp/core/Router',
    'hp/core/UrlFragment',
    'hp/core/LinkTargetBuilder',
    'hp/core/Notifications',
    'hp/core/EventDispatcher',
    'hp/services/REST',
    'hp/model/Session',
    'hp/core/Localizer'], 

function (resource, baselinePresenter, nodePresenter, indexService, router, urlFragment,
linkTargetBuilder, notifications, EventDispatcher, restService, session, localizer) {"use strict";

	var GroupPresenter = ( function() {

			/**
			 * @constructor
			 */
			function GroupPresenter() {

				var dispatcher = new EventDispatcher(),
				    groups = [],
				    baselines = [],
				    nodes = [],
				    selectedItem = '',
				    lastLocation = '',
				    lastAction = '',
				    trackUri = null,
					itemschanged = null,
				    initDone = false,
					allGroups = null;

				var task = {
					category : 'task',
					name : localizer.getString('hpsum.group.addingNewGroup'),
					uri : '/task/task-' + (new Date()).getTime(),
					status : 'unknown',
					changing : true,
					sourceUri : null,
					sourceName : null,
					date : null,
					state : 'running',
					progress : 10,
					progressStep : 'Initializing',
					owner : session.getUser()
				};

				function getItem() {
					
					var uris = resource.getSelection().uris;
					if (uris && uris.length > 0) {
						itemschanged = null;
						resource.getItem(uris[0], {
							success : function(item) {
								selectedItem = item;
								itemschanged = item;
								dispatcher.fire("itemChange", item);
							},
							error : function(errorMessage) {
								dispatcher.fire("itemError", errorMessage);
							}
						});
					}
				}

				function selectionChange(selection) {
					dispatcher.fire("selectionChange", selection);
					if (selection.uris) {
						if (!selection.multiSelectId) {
							getItem();
						} else {
						}
					}
				}-

				function onAddGroupError(data) {

				}


				this.getAllNodes = function(handlers) {
					var localHandlers = {
						success : function(data) {
							nodes = [];
							var hapiNodes = data.hapi.output_data.nodes.node;
							var idx = 0;
							for ( idx = 0; idx < hapiNodes.length; ++idx) {
								var hapiNode = hapiNodes[idx];
								var node = {
									node_status : hapiNode.node_status,
									state : hapiNode.node_state,
									node_state : hapiNode.node_state,
									node_phase : hapiNode.node_phase,
									return_code : hapiNode.return_code,
									name : hapiNode.node_name,
									type : hapiNode.type,
									uri : hapiNode.node_uri,
									id : hapiNode.node_id,
									session_id : hapiNode.node_session
								};
								nodes.push(node);
								handlers.success(data);
							}
						},
						error : function(msg) {
							handlers.error(msg);
						}
					};
					nodePresenter.getAllNodes(localHandlers);
				};

				this.refreshAllBaselines = function() {
					baselinePresenter.getBaselines({
						success : function(data) {
							baselines = [];
							var i = 0, baselineid;
							var paths = [];
							for ( i = 0; i < data.length; i++) {
								if (data[i].hasOwnProperty("baseline_id")) {
									var str = data[i].baseline_url;
									str = str.replace(new RegExp(/\\/g), "/");

									var baseline_version = "";
									if (data[i].baseline_version !== "N/A")
									    var baseline_version = ' ' + data[i].baseline_version;

									var obj = {
										id : data[i].locationid + '/' + data[i].baseline_id,
										name : data[i].baseline_name + ' at ' + str,
										raw_name : str,
										uri: data[i].baseline_uri,
										version: data[i].baseline_version,
										baseline_name: data[i].baseline_name + baseline_version,
										baseline_status: data[i].baseline_status
									};
									baselines.push(obj);
								}
							}
						},
						error : function(msg) {
						}
					});
				}; 
				
				this.getAllBaselines = function(handlers) {
					baselinePresenter.getBaselines({
						success : function(data) {
							baselines = [];
							var i = 0, baselineid;
							var paths = [];
							for ( i = 0; i < data.length; i++) {
								if (data[i].hasOwnProperty("baseline_id")) {
									var str = data[i].baseline_url;
									str = str.replace(new RegExp(/\\/g), "/");
									var baseline_version = "";
									if (data[i].baseline_version !== "N/A")
									    var baseline_version = ' ' + data[i].baseline_version;

									var obj = {
										id : data[i].locationid + '/' + data[i].baseline_id,
										name : data[i].baseline_name + ' at ' + str,
										raw_name : str,
										uri: data[i].baseline_uri,
										version: data[i].baseline_version,
										baseline_name: data[i].baseline_name + baseline_version,
										baseline_status : data[i].baseline_status
									};
									baselines.push(obj);
								}
							}
							if (handlers)
								handlers.success(baselines);
						},
						error : function(msg) {
							if (handlers) {
								handlers.error(msg);
							}
						}
					});
				}; 

				this.getInstallSetAndTaskQueue = function (handlers) {
				    if (selectedItem.hapi) {
				        var uri = '/Session/' + session.getToken() + '/node/group/' + selectedItem.hapi.group_id + '/getgroupinstallsets';
				        restService.getURI(uri, {
				            success: function (data) {
				                var installSetList = [],
                                taskQueueFlag = false;
				                if (data.hapi.hasOwnProperty("install_sets")) {
				                    for (var i = 0; i < data.hapi.install_sets.length; i++) {
				                        installSetList.push(data.hapi.install_sets[i]);
				                    }
				                }
				                taskQueueFlag = data.hapi.is_taskqueue_present;

				                if (data.hapi.hcode == 0) {
				                    handlers.success(installSetList, taskQueueFlag);
				                }
				            },
				            error: function (msg) {
				                handlers.error(msg);
				            }
				        });
				    }
				}; 
			

				
				this.getBaselineArray = function() {
					return baselines;
				}

				this.getNodeArray = function() {
					return nodes;
					;
				}

				this.getGroupArray = function() {
					return groups;
				}

				this.getData = function(handlers) {
					getItem();
					var uri = '/Session/' + session.getToken() + '/node/group/' + selectedItem.hapi.group_id + '/getdata';
					restService.getURI(uri, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
							}
						},
						error : function(data) {
							handlers.error(data);
						}
					});
				};

				this.getNodesData = function(groupItem, handlers) {
					var uri = '/Session/' + session.getToken() + '/node/group/' + groupItem.group_id + '/getnodesdata';
					restService.getURI(uri, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
							}
						},
						error : function(data) {
							handlers.error(data);
						}
					});
				};
				
				this.getUpdateList = function(item, handlers) {
					var uri = 'Session/' + session.getToken() + '/node/group/' + item.group_id + '/getupdatelist';
					restService.getURI(uri, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
							}
						},
						error : function(data) {
							handlers.error(data);
						}
					});
				}				
			
				this.setAttributes = function(item, options, handlers) {
					var uri = '/Session/' + session.getToken() + '/node/group/' + item.group_id + '/setattributes';
					restService.postObject(uri, options, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
							} else
								handlers.error(data.hapi.hmessage);
						},
						error : function(data) {
							handlers.error(data);
						}
					}, null);
				}; 
				
				this.getAttributes = function(item,handlers){
					var uri = '/Session/' + session.getToken() + '/node/group/' + item.group_id + '/getattributes';
					restService.getURI(uri, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
							} else
								handlers.error(data);
						},
						error : function(data) {
							handlers.error(data);
						}
					});
				}
			
				this.analysis = function(item, complist, handlers) {
					var uri = '/Session/' + session.getToken() + '/node/group/' + item.group_id + '/analysis';
					restService.postObject(uri, complist, "", handlers, {});
				};
				
				this.deploy = function(item, handlers) {
					var uri = '/Session/' + session.getToken() + '/node/group/' + item.group_id + '/deploy';
					var scheduledDateTime = item.hasOwnProperty('set_group_schedule_date_time') ? item.set_group_schedule_date_time : "";
					var cleanuponexit = item.hasOwnProperty('cleanup_onexit') ? item.cleanup_onexit : false;
					var cleanupallonexit = item.hasOwnProperty('cleanupall_onexit') ? item.cleanupall_onexit : false;
					var stageOnly = item.hasOwnProperty('stage_only') ? item.stage_only : false;

                    var object = {
                        hapi : {
                            schedule_date_time : scheduledDateTime,
							cleanupall_onexit : cleanupallonexit,
							cleanup_onexit: cleanuponexit,
							stage_only: stageOnly
                            }
                        
                    };				
					
					restService.postObject(uri, object, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
								resource.getIndexResults();
							} else
								handlers.error(data.hapi.hmessage);
						},
						error : function(data) {
							handlers.error(data);
						}
					}, null);
				};

				this.abortItem = function(group, clearScheduleDateTime, handlers) {
					var uri = '/session/' + session.getToken() + '/node/group/' + group.group_id + '/abort';
					restService.postObject(uri, clearScheduleDateTime, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
							} else
								handlers.error(data.hapi.hmessage);
						},
						error : function(data) {
							handlers.error(data);
						}
					}, null);
				};

				this.deleteItem = function(group, handlers) {
					var uri = '/session/' + session.getToken() + '/node/group/' + group.group_id + '/remove';
					restService.postObject(uri, null, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
								resource.removeSelectedUri('/session/' + session.getToken() + '/node/group/' + group.group_id + '/getdata');
								resource.getIndexResults();
							} else
								handlers.error(data.hapi.hmessage);
						},
						error : function(data) {
							handlers.error(data);
						}
					}, null);
				};
				
				this.restore = function(group, handlers) {
					var uri = '/Session/' + session.getToken() + '/node/group/' + group.group_id + '/restore';
					restService.postObject(uri, null, {
						success : function(data) {
							resource.getIndexResults();
							handlers.success(data);
						},
						error : function(data) {
							handlers.error(data);
						}
					}, null);
				}; 
        
				this.getBaselineDetailsforId = function(baselineId) {
					var i;
					if (baselineId == '')
						return null;
					for ( i = 0; i < baselines.length; i++) {
						if (baselines[i].id.match(baselineId))
							return baselines[i];
					}
					return null;
				};

				this.getGroupIndex = function(handlers) {
					var groupIndexHandlers = {
					    success: function (data) {
							if (handlers) {
								handlers.success(data);
							}
						},
						error : function(msg) {
							if (handlers) {
								handlers.error(msg);
							}
						}
					};
					restService.getURI('/session/' + session.getToken() + '/node/group/index', indexGroups(groupIndexHandlers, groups));
				};

				this.getGroupIndexDetails = function (handlers) {
				    var groupIndexHandlers = {
				        success: function (data) {
				            if (handlers) {
				                var groupsList = [];
				                for (var idx = 0; idx < data.hapi.output_data.groups.group.length; idx++) {
				                    var obj = {
				                        id: data.hapi.output_data.groups.group[idx].group_id,
				                        name: data.hapi.output_data.groups.group[idx].group_name,
				                        group_state: data.hapi.output_data.groups.group[idx].group_state,
				                        group_phase: data.hapi.output_data.groups.group[idx].group_phase,
				                        group_baselines: data.hapi.output_data.groups.group[idx].group_baselines
				                    };
				                    groupsList.push(obj);
				                }
				                handlers.success(groupsList);
				            }
				        },
				        error: function (msg) {
				            if (handlers) {
				                handlers.error(msg);
				            }
				        }
				    };
				    restService.getURI('/session/' + session.getToken() + '/node/group/index', indexGroups(groupIndexHandlers, groups));
				};

				function indexGroups(handlers, groups) {
					var groupDataHandlers = {
						success : function(data) {
							groups.push(data);
						},
						error : function(errorInfo) {
							if (handlers) {
								handlers.error(errorInfo);
							}
						}
					};
					return {
						success : function(data) {
							var i;
							var uri;
							groups = [];
							for ( i = 0; i < data.hapi.output_data.groups.group.length; ++i) {
								var hapiGroup = data.hapi.output_data.groups.group[i];
								restService.getURI('/session/' + session.getToken() + '/node/group/' + hapiGroup.group_id + '/getdata', groupDataHandlers);
							}
							handlers.success(data);
						},
						error : function(data) {
							handlers.error(data);
						}
					};
				}


				this.haveItems = function() {
					return resource.haveSome();
				};

				this.selectionLabel = function() {
					return selectedItem.hapi.name;
				};

				this.getGroupStatus = function(item, handlers) {
					var uri = '/session/' + session.getToken() + '/node/group/' + item.group_id + '/getstatus';
					var thishandlers = {
						success : function(data) {
							handlers.success(data);
						},
						error : function(errorInfo) {
							handlers.error(errorInfo);
						}
					};
					restService.getURI(uri, thishandlers);
				}

				this.startInventory = function(item, handlers) {
					var uri = '/session/' + session.getToken() + '/node/group/' + item.group_id + '/inventory';
					 var scheduledDateTime = item.hasOwnProperty('set_group_schedule_date_time') ? item.set_group_schedule_date_time : "";
					var operationMode = item.hasOwnProperty('operation_mode') ? item.operation_mode : 0;
					var skipnodes = item.hasOwnProperty('skip_nodes') ? item.skip_nodes : 0;
					var object = {
						hapi : {
							operation_mode : operationMode,
							skip_nodes : skipnodes,
                            schedule_date_time : scheduledDateTime,
							group_baselines : {
								remove_existing_baselines:'true',
								group_baseline : item.baselines
							}
						}
					};
					restService.postObject(uri, object, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
								resource.getIndexResults();
							} else
								handlers.error(data.hapi.hmessage);
						},
						error : function(data) {
							handlers.error(data);
						}
					}, null);
				};

				function onAddGroupSuccess(data) {
					task.name = localizer.getString('hpsum.group.addedNewGroup');
					task.status = 'ok';
					var notif = {
						summary : task.name,
						uri : task.uri,
						status : task.status,
						sourceName : task.sourceName,
						sourceUri : task.sourceUri,
						progress : task.progress,
						step : task.progressStep
					};
					notif.summary = localizer.getString('hpsum.group.addedNewGroup');
					notif.status = task.status;
					notifications.add(notif, true);
					if (task.sourceUri === trackUri) {
						dispatcher.fire('notificationChange', notif);
					}
				}
				
				this.addItem = function(item, selectItem, handlers) {
					task.sourceName = item.name;
					task.sourceUri = item.uri;
					task.date = item.date;
					var notif = {
						summary : task.name,
						uri : task.uri,
						status : task.status,
						sourceName : task.sourceName,
						sourceUri : task.sourceUri,
						progress : task.progress,
						step : task.progressStep
					};
					notifications.add(notif, true);
					item.status = 'unknown';

					resource.addGroup(item, {
						success : function(data) {
							if (data.hapi.hcode == 0){
							    onAddGroupSuccess(data);
								if (selectItem) {
									var itemUri = '/session/' + session.getToken() + '/node/group/' + data.hapi.group_id + '/getdata';
									resource.setSelectedUris([itemUri]);
								}
								resource.getIndexResults({
								    error: function () {

								    },
								    success: function () {
								        dispatcher.fire('itemChange', item);
								        handlers.success(data);
								    }
								});
								
							}
							else if (data.hapi.hcode == 5032) {
								handlers.success(data);
							} else {
								handlers.error(data);
							}
						},
						error : function(data) {
							handlers.error(data);
						}
					});
					trackUri = item.uri;
					resource.getIndexResults();
					if (item.uri === trackUri) {
						dispatcher.fire('notificationChange', notif);
					}

				};

				this.refreshIndexResults = function() {
					resource.getIndexResults();
				};

				this.editItem = function(groupItem, item, handlers) {
					var uri = '/session/' + session.getToken() + '/node/group/' + groupItem.group_id + '/edit';
					var object = {
						hapi : {
							group_name : item.name,
							group_description : item.description,
							group_nodes : {
								group_node : item.nodes
							}
						}
					};

					restService.postObject(uri, object, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
								resource.getIndexResults();
							} else if (data.hapi.hcode == 5030) {
								handlers.success(data);
							}else {
								handlers.error(data.hapi.hmessage);
							}
						},
						error : function(data) {
							handlers.error(data);
						}
					}, null);

				};

				this.removeNodes = function(groupItem, item, handlers, refresh) {
					var uri = '/session/' + session.getToken() + '/node/group/' + groupItem.group_id + '/removenodes';
					var object = {
						hapi : {
							group_nodes : {
								group_node : item.nodes
							}
						}
					};

					restService.postObject(uri, object, {
						success : function(data) {
							if (data.hapi.hcode == 0) {
								handlers.success(data);
								if(!refresh){
									resource.getIndexResults();
								}
							} else
								handlers.error(data.hapi.hmessage);
						},
						error : function(data) {
							handlers.error(data);
						}
					}, null);
				};

				/**
				 * @public
				 */
				this.init = function() {
					this.refreshAllBaselines();
					resource.setCompareResourcesFunction(indexResultsCompare);
					resource.on("selectionChange", selectionChange);
					initDone = true;
					this.getGroupIndex();
				};

				function indexResultsCompare(last, latest) {
					
					//Check if path has changed from last time.
					var loc = router.location().split('/');
					if ((loc.length < 6) && (loc[2] == 'show'))
						return false;
					var location = loc[1];
					var action = loc[2];

					if (lastLocation != location || lastAction != action) {
						lastLocation = location;
						lastAction = action;
						return false;
					}
					if(last.group_name != latest.group_name)
					{
						return false;
					}
					if ((last.group_state == latest.group_state) &&
						(last.group_phase == latest.group_phase) &&
						(last.group_status == latest.group_status) &&
					    (last.group_name == latest.group_name) &&
					    (last.group_description == latest.group_description) &&
					    (last.group_nodes.group_node.length == latest.group_nodes.group_node.length))
					{
						return true;
					}
					return false;
				}

				this.resource = function() {
					return resource;
				}

				this.getSelection = function() {
					return resource.getSelection();
				};

				this.allBaselines = function() {
					return allBaselines;
				}

				this.getAddLink = function() {
					var result = null;
					if (session.canPerformAction('GROUP', 'ADD')) {
						result = linkTargetBuilder.makeLink(localizer.getString('hpsum.group.addGroup'), null, 'add', 'group', 'ADD');
					}
					return result;
				};

				this.fireItemChange = function()
				{
					dispatcher.fire("itemChange", itemschanged);
				};
				
				/**
				 * @public
				 * Turn on a specific event
				 *
				 */
				this.on = function(eventName, callback) {
					var uris;
					dispatcher.on(eventName, callback);
					switch (eventName) {
						case 'selectionChange':
							callback(resource.getSelection());
							break;
						case 'itemChange':
							uris = resource.getSelection().uris;
							if (uris && uris.length === 1) {
								resource.getItem(uris[0], {
									success : callback
								});
							}
							break;
						case 'itemError':
							uris = resource.getSelection().uris;
							if (uris && uris.length === 1) {
								resource.getItem(uris[0], {
									error : callback
								});
							}
							break;
					}
				};
				this.ScheduleNodes = function(groupItem, action, scheduled, schedule_information, handlers)
				{
					var uri = '/session/'+ session.getToken() + '/node/group/' + groupItem.group_id + '/schedule' ;
					var object={
							hapi: {
								  action : action,
								  scheduled : scheduled,
								  schedule_information: schedule_information,
								  group_name : groupItem.group_name
							}
					};
					restService.postObject(uri,object, {
								success : function(data) {
									if (data.hapi.hcode == 0) {
										handlers.success(data);
										resource.getIndexResults();
									}
									else
										handlers.error(data.hapi.hmessage);
								},
								error: function (){
									handlers.error()
								}
							}, null);
				};
				/**
				 * @public
				 * Turn off a specific event
				 */
				this.off = function(eventName, callback) {
					dispatcher.off(eventName, callback);
				};
			}

			return new GroupPresenter();
		}());

	return GroupPresenter;
});

