<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
  var vmMigrationHostObjs;
  cloudStack.sections.instances = {
    title: 'label.instances',
    id: 'instances',
    listView: {
      section: 'instances',
      filters: {
        all: { label: 'ui.listView.filters.all' },
        mine: { label: 'ui.listView.filters.mine' },
        running: { label: 'state.Running' },
        stopped: { label: 'state.Stopped' },
        destroyed: {
          preFilter: function(args) {
            if (isAdmin() || isDomainAdmin())
              return true;
            else
              return false;
          },
          label: 'state.Destroyed'
        }
      },
			preFilter: function(args) {
				var hiddenFields = [];
				if(!isAdmin()) {
					hiddenFields.push('instancename');
				}
				return hiddenFields;
			},
      fields: {
				name: { label: 'label.name' },
				instancename: { label: 'label.internal.name' },
				displayname: { label: 'label.display.name' },
        zonename: { label: 'label.zone.name' },
        state: {
          label: 'label.state',
          indicator: {
            'Running': 'on',
            'Stopped': 'off',
            'Destroyed': 'off',
            'Error': 'off'
          }
        }
      },

			advSearchFields: {
				name: { label: 'Name' },
				zoneid: {
					label: 'Zone',
					select: function(args) {
						$.ajax({
							url: createURL('listZones'),
							data: {
								listAll: true
							},
							success: function(json) {
								var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : [];

								args.response.success({
									data: $.map(zones, function(zone) {
										return {
											id: zone.id,
											description: zone.name
										};
									})
								});
							}
						});
					}
				},

				domainid: {
				  label: 'Domain',
					select: function(args) {
					  if(isAdmin() || isDomainAdmin()) {
							$.ajax({
								url: createURL('listDomains'),
								data: {
									listAll: true,
									details: 'min'
								},
								success: function(json) {
									var array1 = [{id: '', description: ''}];
									var domains = json.listdomainsresponse.domain;
									if(domains != null && domains.length > 0) {
										for(var i = 0; i < domains.length; i++) {
											array1.push({id: domains[i].id, description: domains[i].path});
										}
									}
									args.response.success({
										data: array1
									});
								}
							});
						}
						else {
						  args.response.success({
								data: null
							});
						}
					},
					isHidden: function(args) {
					  if(isAdmin() || isDomainAdmin())
						  return false;
						else
						  return true;
					}
				},
        account: {
				  label: 'Account',
          isHidden: function(args) {
					  if(isAdmin() || isDomainAdmin())
						  return false;
						else
						  return true;
					}
				},

				tagKey: { label: 'Tag Key' },
				tagValue: { label: 'Tag Value' }
			},

      // List view actions
      actions: {
        // Add instance wizard
        add: {
          label: 'label.vm.add',

          action: {
            custom: cloudStack.uiCustom.instanceWizard(cloudStack.instanceWizard)
          },

          messages: {
            notification: function(args) {
              return 'label.vm.add';
            }
          },
          notification: {
            poll: pollAsyncJobResult
          }
        }
      },

      dataProvider: function(args) {
			  var data = {};
				listViewDataProvider(args, data);

				if(args.filterBy != null) {	//filter dropdown
					if(args.filterBy.kind != null) {
						switch(args.filterBy.kind) {
						case "all":
							break;
						case "mine":
							if (!args.context.projects) {
							  $.extend(data, {
								  domainid: g_domainid,
									account: g_account
								});
              }
							break;
						case "running":
						  $.extend(data, {
							  state: 'Running'
							});
							break;
						case "stopped":
						  $.extend(data, {
							  state: 'Stopped'
							});
							break;
						case "destroyed":
						  $.extend(data, {
							  state: 'Destroyed'
							});
							break;
						}
					}
				}

        if("hosts" in args.context) {
					$.extend(data, {
					  hostid: args.context.hosts[0].id
					});
				}
				
				if("affinityGroups" in args.context) {				  
					$.extend(data, {
					  affinitygroupid: args.context.affinityGroups[0].id
					});		
				}

        if("vpc" in args.context &&
           "networks" in args.context) {
          $.extend(data, {
            vpcid: args.context.vpc[0].id,
            networkid: args.context.networks[0].id
          });
        }
              
        $.ajax({
          url: createURL('listVirtualMachines'),
          data: data,
          success: function(json) {
            var items = json.listvirtualmachinesresponse.virtualmachine;           
            args.response.success({
              actionFilter: vmActionfilter,
              data: items
            });
          }
        });
      },

      detailView: {
        name: 'Instance details',
        viewAll: [
          { path: 'storage.volumes', label: 'label.volumes' },
          { path: 'vmsnapshots', label: 'label.snapshots' },
					{ path: 'affinityGroups', label: 'label.affinity.groups' },
          {
            path: '_zone.hosts',
            label: 'label.hosts',
            preFilter: function(args) {
              return isAdmin();
            },
            updateContext: function(args) {
              var instance = args.context.instances[0];
              var zone;

              $.ajax({
                url: createURL('listZones'),
                data: {
                  id: instance.zoneid
                },
                async: false,
                success: function(json) {
                  zone = json.listzonesresponse.zone[0]
                }
              });

              return { zones: [zone] };
            }
          }
        ],
        tabFilter: function(args) {
          var hiddenTabs = [];
					
					var zoneObj;
          $.ajax({
            url: createURL("listZones&id=" + args.context.instances[0].zoneid),
            dataType: "json",
            async: false,
            success: function(json) {              
							zoneObj = json.listzonesresponse.zone[0];
            }
          });
					
					var includingSecurityGroupService = false;
          if(zoneObj.networktype == "Basic") { //Basic zone           
            $.ajax({
              url: createURL("listNetworks&id=" + args.context.instances[0].nic[0].networkid),
              dataType: "json",
              async: false,
              success: function(json) {
                var items = json.listnetworksresponse.network;
                if(items != null && items.length > 0) {
                  var networkObj = items[0];    //Basic zone has only one guest network (only one NIC)    
                  var serviceObjArray = networkObj.service;
                  for(var k = 0; k < serviceObjArray.length; k++) {
                    if(serviceObjArray[k].name == "SecurityGroup") {
                      includingSecurityGroupService = true;
                      break;
                    }
                  }
                }
              }
            });
          }
          else if(zoneObj.networktype == "Advanced") { //Advanced zone    
            if(zoneObj.securitygroupsenabled == true)	
              includingSecurityGroupService = true;
						else
						  includingSecurityGroupService = false;						
          }
					
					if(includingSecurityGroupService == false) {
            hiddenTabs.push("securityGroups");
					}
					
          return hiddenTabs;
        },
        actions: {
          start: {
            label: 'label.action.start.instance' ,
            action: function(args) {
              $.ajax({
                url: createURL("startVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.startvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            messages: {
              confirm: function(args) {
                return 'message.action.start.instance';
              },
              notification: function(args) {
                return 'label.action.start.instance';
              },							
							complete: function(args) {
								if(args.password != null) {
									return 'Password of the VM is ' + args.password;
								}

								return false;
							}			
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },
          stop: {
            label: 'label.action.stop.instance',
            compactLabel: 'label.stop',
            createForm: {
              title: 'Stop instance',
              desc: 'message.action.stop.instance',
              fields: {
                forced: {
                  label: 'force.stop',
                  isBoolean: true,
                  isChecked: false
                }
              }
            },
            action: function(args) {
              var array1 = [];
              array1.push("&forced=" + (args.data.forced == "on"));
              $.ajax({
                url: createURL("stopVirtualMachine&id=" + args.context.instances[0].id + array1.join("")),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.stopvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            messages: {
              confirm: function(args) {
                return 'message.action.stop.instance';
              },
              notification: function(args) {
                return 'label.action.stop.instance';
              }
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },
          restart: {
            label: 'label.action.reboot.instance',
            compactLabel: 'label.reboot',
            action: function(args) {
              $.ajax({
                url: createURL("rebootVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.rebootvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            messages: {
              confirm: function(args) {
                return 'message.action.reboot.instance';
              },
              notification: function(args) {
                return 'label.action.reboot.instance';
              }
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },
          snapshot: {
            messages: {
              notification: function(args) {
                return 'label.action.vmsnapshot.create';
              }
            },
            label: 'label.action.vmsnapshot.create',
            addRow: 'false',
            createForm: {
              title: 'label.action.vmsnapshot.create',
              fields: {
                name: {
                  label: 'label.name',
                  isInput: true
                },
                description: {
                  label: 'label.description',
                  isTextarea: true
                },
                snapshotMemory: {
                  label: 'label.vmsnapshot.memory',
                  isBoolean: true,
                  isChecked: false
                }
              }
            },
            action: function(args) {
              var array1 = [];
              array1.push("&snapshotmemory=" + (args.data.snapshotMemory == "on"));
              var displayname = args.data.name;
              if (displayname != null && displayname.length > 0) {
                array1.push("&name=" + todb(displayname));
              }
              var description = args.data.description;
              if (description != null && description.length > 0) {
                array1.push("&description=" + todb(description));
              }
              $.ajax({
                url: createURL("createVMSnapshot&virtualmachineid=" + args.context.instances[0].id + array1.join("")),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.createvmsnapshotresponse.jobid;
                  args.response.success({
                    _custom: {
                      jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                    }
                  });
                }
              });
          
            },
            notification: {
              pool: pollAsyncJobResult
            }
          },          
          destroy: {
            label: 'label.action.destroy.instance',
            compactLabel: 'label.destroy',
            messages: {
              confirm: function(args) {
                return 'message.action.destroy.instance';
              },
              notification: function(args) {
                return 'label.action.destroy.instance';
              }
            },
            action: function(args) {
              $.ajax({
                url: createURL("destroyVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.destroyvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },
          restore: {
            label: 'label.action.restore.instance',
            compactLabel: 'label.restore',
            messages: {
              confirm: function(args) {
                return 'message.action.restore.instance';
              },
              notification: function(args) {
                return 'label.action.restore.instance';
              }
            },
            action: function(args) {
              $.ajax({
                url: createURL("recoverVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var item = json.recovervirtualmachineresponse.virtualmachine;
                  args.response.success({data:item});
                }
              });
            },
            notification: {
              poll: function(args) {
                args.complete({ data: { state: 'Stopped' }});
              }
            }
          },
          reset: {
            label: 'Reset VM',
            messages:{
              confirm:function(args) {
                 return 'Do you want to restore the VM ?';
                },
               notification:function(args) {
                return 'Reset VM';
               }
            },

            action:function(args){
                $.ajax({
                url: createURL("restoreVirtualMachine&virtualmachineid=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var item = json.restorevmresponse;
                  args.response.success({data:item});
                }
              });

            },

           notification: {
              poll: function(args) {
                args.complete({ data: { state: 'Stopped' }});
              }
            }

          },

          changeAffinity: {
            label: 'Change affinity',

            action: {
              custom: cloudStack.uiCustom.affinity({
                tierSelect: function(args) {
                  if ('vpc' in args.context) { //from VPC section
                    args.$tierSelect.show(); //show tier dropdown

                    $.ajax({ //populate tier dropdown
                      url: createURL("listNetworks"),
                      async: false,
                      data: {
                        vpcid: args.context.vpc[0].id,
                        //listAll: true,  //do not pass listAll to listNetworks under VPC
											  domainid: args.context.vpc[0].domainid,
						            account: args.context.vpc[0].account,
                        supportedservices: 'StaticNat'
                      },
                      success: function(json) {
                        var networks = json.listnetworksresponse.network;
                        var items = [{ id: -1, description: 'Please select a tier' }];
                        $(networks).each(function(){
                          items.push({id: this.id, description: this.displaytext});
                        });
                        args.response.success({ data: items });
                      }
                    });
                  }
                  else { //from Guest Network section
                    args.$tierSelect.hide();
                  }

                  args.$tierSelect.change(function() {
                    args.$tierSelect.closest('.list-view').listView('refresh');
                  });
                  args.$tierSelect.closest('.list-view').listView('refresh');
                },

                listView: {
                  listView: {
                    id: 'affinityGroups',
                    fields: {
                      name: { label: 'label.name' },
                      type: { label: 'label.type' }
                    },
                    dataProvider: function(args) {				
                      var data = {
                        domainid: args.context.instances[0].domainid,
                        account: args.context.instances[0].account
                      };                    
											$.ajax({
												url: createURL('listAffinityGroups'),
												data: data,
												async: false, //make it sync to avoid dataProvider() being called twice which produces duplicate data
												success: function(json) {	
                          var items = [];												
													var allAffinityGroups = json.listaffinitygroupsresponse.affinitygroup;
													var previouslySelectedAffinityGroups = args.context.instances[0].affinitygroup;
													if(allAffinityGroups != null) {		
													  for(var i = 0; i < allAffinityGroups.length; i++) {														  
														  var isPreviouslySelected = false;														  
															if(previouslySelectedAffinityGroups != null) {
															  for(var k = 0; k < previouslySelectedAffinityGroups.length; k++) {
																  if(previouslySelectedAffinityGroups[k].id == allAffinityGroups[i].id) {
																	  isPreviouslySelected = true;
																	  break; //break for loop
																	}
																}																
															}												
															items.push($.extend(allAffinityGroups[i], {
															  _isSelected: isPreviouslySelected
															}));	                             													
														}
													}											
													args.response.success({data: items});
												}
											});													
                    }
                  }
                },
                action: function(args) {                  
									var affinityGroupIdArray = [];
									if(args.context.affinityGroups != null) {
									  for(var i = 0; i < args.context.affinityGroups.length; i++) {										  
											if(args.context.affinityGroups[i]._isSelected == true) {
											  affinityGroupIdArray.push(args.context.affinityGroups[i].id);
											}
										}
									}									
									var data = {
									  id: args.context.instances[0].id,
										affinitygroupids: affinityGroupIdArray.join(",")
									};									
									$.ajax({
									  url: createURL('updateVMAffinityGroup'),
										data: data,
										success: function(json) {										  
											var jid = json.updatevirtualmachineresponse.jobid;											
											args.response.success(
												{_custom:
												 {jobId: jid,
													getUpdatedItem: function(json) {													  
														return json.queryasyncjobresultresponse.jobresult.virtualmachine;
													},
													getActionFilter: function() {
														return vmActionfilter;
													}
												 }
												}
											);												
										}
									});			
                }
              })
            },
            messages: {
              notification: function(args) {
                return 'Change affinity';
              }
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },

          edit: {
            label: 'label.edit',
            action: function(args) {
						  var data = {
							  id: args.context.instances[0].id,
							  group: args.data.group,
							  isdynamicallyscalable: (args.data.isdynamicallyscalable=="on"),
								ostypeid: args.data.guestosid
							};
						  
							if(args.data.displayname != args.context.instances[0].displayname) {
							  $.extend(data, {
								  displayName: args.data.displayname
								});							
							}								

              $.ajax({
                url: createURL('updateVirtualMachine'),
                data: data,
                success: function(json) {
                  var item = json.updatevirtualmachineresponse.virtualmachine;
                  args.response.success({data:item});
                }
              });
            }
          },

          attachISO: {
            label: 'label.action.attach.iso',
            createForm: {
              title: 'label.action.attach.iso',             
              fields: {
                iso: {
                  label: 'ISO',
                  select: function(args) {
									  var items = [];
										var map = {};
                    $.ajax({
                      url: createURL("listIsos&isReady=true&isofilter=featured"),
                      dataType: "json",
                      async: false,
                      success: function(json) {
                        var isos = json.listisosresponse.iso;                        
                        $(isos).each(function() {
                          items.push({id: this.id, description: this.displaytext});
													map[this.id] = 1;
                        });                        
                      }
                    });
										$.ajax({
                      url: createURL("listIsos&isReady=true&isofilter=community"),
                      dataType: "json",
                      async: false,
                      success: function(json) {
                        var isos = json.listisosresponse.iso;                        
                        $(isos).each(function() {												  
													if(!(this.id in map)) {
                            items.push({id: this.id, description: this.displaytext});
														map[this.id] = 1;
													}
                        });                        
                      }
                    });
										$.ajax({
                      url: createURL("listIsos&isReady=true&isofilter=selfexecutable"),
                      dataType: "json",
                      async: false,
                      success: function(json) {
                        var isos = json.listisosresponse.iso;                        
                        $(isos).each(function() {												 
													if(!(this.id in map)) {
                            items.push({id: this.id, description: this.displaytext});
														map[this.id] = 1;
													}
                        });                             
                      }
                    });
																				
										args.response.success({data: items});
                  }
                }
              }
            },
            action: function(args) {
              $.ajax({
                url: createURL("attachIso&virtualmachineid=" + args.context.instances[0].id + "&id=" + args.data.iso),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.attachisoresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            messages: {             
              notification: function(args) {
                return 'label.action.attach.iso';
              }
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },

          detachISO: {
            label: 'label.action.detach.iso',
            messages: {
              confirm: function(args) {
                return 'message.detach.iso.confirm';
              },
              notification: function(args) {
                return 'label.action.detach.iso';
              }
            },
            action: function(args) {
              $.ajax({
                url: createURL("detachIso&virtualmachineid=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.detachisoresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },

          resetPassword: {
            label: 'label.action.reset.password',
            messages: {
              confirm: function(args) {
                return 'message.action.instance.reset.password';
              },
              notification: function(args) {
                return 'label.action.reset.password';
              },
              complete: function(args) {
                return 'Password has been reset to ' + args.password;
              }
            },

            preAction: function(args) {
              var jsonObj = args.context.instances[0];
              if (jsonObj.passwordenabled == false) {
                cloudStack.dialog.notice({ message: 'message.reset.password.warning.notPasswordEnabled' });
                return false;
              }
              else if (jsonObj.state != 'Stopped') {
                cloudStack.dialog.notice({ message: 'message.reset.password.warning.notStopped' });
                return false;
              }
              return true;
            },

            action: function(args) {
              $.ajax({
                url: createURL("resetPasswordForVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.resetpasswordforvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },

          changeService: {
            label: 'label.action.change.service',
            messages: {
              notification: function(args) {
                return 'label.action.change.service';
              }
            },
            createForm: {
              title: 'label.action.change.service',
              desc: '',
              fields: {
                serviceOffering: {
                  label: 'label.compute.offering',
                  select: function(args) {
                    $.ajax({
                      url: createURL("listServiceOfferings&VirtualMachineId=" + args.context.instances[0].id),
                      dataType: "json",
                      async: true,
                      success: function(json) {
                        var serviceofferings = json.listserviceofferingsresponse.serviceoffering;
                        var items = [];
                        $(serviceofferings).each(function() {
                          items.push({id: this.id, description: this.name});
                        });
                        args.response.success({data: items});
                      }
                    });
                  }
                }
              }
            },

            preAction: function(args) {
              var jsonObj = args.context.instances[0];
              if (jsonObj.state != 'Stopped') {
                cloudStack.dialog.notice({ message: 'message.action.change.service.warning.for.instance' });
                return false;
              }
              return true;
            },

            action: function(args) {
              $.ajax({
                url: createURL("changeServiceForVirtualMachine&id=" + args.context.instances[0].id + "&serviceOfferingId=" + args.data.serviceOffering),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jsonObj = json.changeserviceforvirtualmachineresponse.virtualmachine;
                  args.response.success({data: jsonObj});
                }
              });
            },
            notification: {
              poll: function(args) {
                args.complete();
              }
            }
          },

          createTemplate: {
            label: 'label.create.template',
            messages: {
              confirm: function(args) {
                return 'message.create.template';
              },
              notification: function(args) {
                return 'label.create.template';
              }
            },
            createForm: {
              title: 'label.create.template',
              desc: 'label.create.template',<commit_msg>CLOUDSTACK-2615: Remove 'change service' from VM actions<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
(function($, cloudStack) {
  var vmMigrationHostObjs;
  cloudStack.sections.instances = {
    title: 'label.instances',
    id: 'instances',
    listView: {
      section: 'instances',
      filters: {
        all: { label: 'ui.listView.filters.all' },
        mine: { label: 'ui.listView.filters.mine' },
        running: { label: 'state.Running' },
        stopped: { label: 'state.Stopped' },
        destroyed: {
          preFilter: function(args) {
            if (isAdmin() || isDomainAdmin())
              return true;
            else
              return false;
          },
          label: 'state.Destroyed'
        }
      },
			preFilter: function(args) {
				var hiddenFields = [];
				if(!isAdmin()) {
					hiddenFields.push('instancename');
				}
				return hiddenFields;
			},
      fields: {
				name: { label: 'label.name' },
				instancename: { label: 'label.internal.name' },
				displayname: { label: 'label.display.name' },
        zonename: { label: 'label.zone.name' },
        state: {
          label: 'label.state',
          indicator: {
            'Running': 'on',
            'Stopped': 'off',
            'Destroyed': 'off',
            'Error': 'off'
          }
        }
      },

			advSearchFields: {
				name: { label: 'Name' },
				zoneid: {
					label: 'Zone',
					select: function(args) {
						$.ajax({
							url: createURL('listZones'),
							data: {
								listAll: true
							},
							success: function(json) {
								var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : [];

								args.response.success({
									data: $.map(zones, function(zone) {
										return {
											id: zone.id,
											description: zone.name
										};
									})
								});
							}
						});
					}
				},

				domainid: {
				  label: 'Domain',
					select: function(args) {
					  if(isAdmin() || isDomainAdmin()) {
							$.ajax({
								url: createURL('listDomains'),
								data: {
									listAll: true,
									details: 'min'
								},
								success: function(json) {
									var array1 = [{id: '', description: ''}];
									var domains = json.listdomainsresponse.domain;
									if(domains != null && domains.length > 0) {
										for(var i = 0; i < domains.length; i++) {
											array1.push({id: domains[i].id, description: domains[i].path});
										}
									}
									args.response.success({
										data: array1
									});
								}
							});
						}
						else {
						  args.response.success({
								data: null
							});
						}
					},
					isHidden: function(args) {
					  if(isAdmin() || isDomainAdmin())
						  return false;
						else
						  return true;
					}
				},
        account: {
				  label: 'Account',
          isHidden: function(args) {
					  if(isAdmin() || isDomainAdmin())
						  return false;
						else
						  return true;
					}
				},

				tagKey: { label: 'Tag Key' },
				tagValue: { label: 'Tag Value' }
			},

      // List view actions
      actions: {
        // Add instance wizard
        add: {
          label: 'label.vm.add',

          action: {
            custom: cloudStack.uiCustom.instanceWizard(cloudStack.instanceWizard)
          },

          messages: {
            notification: function(args) {
              return 'label.vm.add';
            }
          },
          notification: {
            poll: pollAsyncJobResult
          }
        }
      },

      dataProvider: function(args) {
			  var data = {};
				listViewDataProvider(args, data);

				if(args.filterBy != null) {	//filter dropdown
					if(args.filterBy.kind != null) {
						switch(args.filterBy.kind) {
						case "all":
							break;
						case "mine":
							if (!args.context.projects) {
							  $.extend(data, {
								  domainid: g_domainid,
									account: g_account
								});
              }
							break;
						case "running":
						  $.extend(data, {
							  state: 'Running'
							});
							break;
						case "stopped":
						  $.extend(data, {
							  state: 'Stopped'
							});
							break;
						case "destroyed":
						  $.extend(data, {
							  state: 'Destroyed'
							});
							break;
						}
					}
				}

        if("hosts" in args.context) {
					$.extend(data, {
					  hostid: args.context.hosts[0].id
					});
				}
				
				if("affinityGroups" in args.context) {				  
					$.extend(data, {
					  affinitygroupid: args.context.affinityGroups[0].id
					});		
				}

        if("vpc" in args.context &&
           "networks" in args.context) {
          $.extend(data, {
            vpcid: args.context.vpc[0].id,
            networkid: args.context.networks[0].id
          });
        }
              
        $.ajax({
          url: createURL('listVirtualMachines'),
          data: data,
          success: function(json) {
            var items = json.listvirtualmachinesresponse.virtualmachine;           
            args.response.success({
              actionFilter: vmActionfilter,
              data: items
            });
          }
        });
      },

      detailView: {
        name: 'Instance details',
        viewAll: [
          { path: 'storage.volumes', label: 'label.volumes' },
          { path: 'vmsnapshots', label: 'label.snapshots' },
					{ path: 'affinityGroups', label: 'label.affinity.groups' },
          {
            path: '_zone.hosts',
            label: 'label.hosts',
            preFilter: function(args) {
              return isAdmin();
            },
            updateContext: function(args) {
              var instance = args.context.instances[0];
              var zone;

              $.ajax({
                url: createURL('listZones'),
                data: {
                  id: instance.zoneid
                },
                async: false,
                success: function(json) {
                  zone = json.listzonesresponse.zone[0]
                }
              });

              return { zones: [zone] };
            }
          }
        ],
        tabFilter: function(args) {
          var hiddenTabs = [];
					
					var zoneObj;
          $.ajax({
            url: createURL("listZones&id=" + args.context.instances[0].zoneid),
            dataType: "json",
            async: false,
            success: function(json) {              
							zoneObj = json.listzonesresponse.zone[0];
            }
          });
					
					var includingSecurityGroupService = false;
          if(zoneObj.networktype == "Basic") { //Basic zone           
            $.ajax({
              url: createURL("listNetworks&id=" + args.context.instances[0].nic[0].networkid),
              dataType: "json",
              async: false,
              success: function(json) {
                var items = json.listnetworksresponse.network;
                if(items != null && items.length > 0) {
                  var networkObj = items[0];    //Basic zone has only one guest network (only one NIC)    
                  var serviceObjArray = networkObj.service;
                  for(var k = 0; k < serviceObjArray.length; k++) {
                    if(serviceObjArray[k].name == "SecurityGroup") {
                      includingSecurityGroupService = true;
                      break;
                    }
                  }
                }
              }
            });
          }
          else if(zoneObj.networktype == "Advanced") { //Advanced zone    
            if(zoneObj.securitygroupsenabled == true)	
              includingSecurityGroupService = true;
						else
						  includingSecurityGroupService = false;						
          }
					
					if(includingSecurityGroupService == false) {
            hiddenTabs.push("securityGroups");
					}
					
          return hiddenTabs;
        },
        actions: {
          start: {
            label: 'label.action.start.instance' ,
            action: function(args) {
              $.ajax({
                url: createURL("startVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.startvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            messages: {
              confirm: function(args) {
                return 'message.action.start.instance';
              },
              notification: function(args) {
                return 'label.action.start.instance';
              },							
							complete: function(args) {
								if(args.password != null) {
									return 'Password of the VM is ' + args.password;
								}

								return false;
							}			
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },
          stop: {
            label: 'label.action.stop.instance',
            compactLabel: 'label.stop',
            createForm: {
              title: 'Stop instance',
              desc: 'message.action.stop.instance',
              fields: {
                forced: {
                  label: 'force.stop',
                  isBoolean: true,
                  isChecked: false
                }
              }
            },
            action: function(args) {
              var array1 = [];
              array1.push("&forced=" + (args.data.forced == "on"));
              $.ajax({
                url: createURL("stopVirtualMachine&id=" + args.context.instances[0].id + array1.join("")),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.stopvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            messages: {
              confirm: function(args) {
                return 'message.action.stop.instance';
              },
              notification: function(args) {
                return 'label.action.stop.instance';
              }
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },
          restart: {
            label: 'label.action.reboot.instance',
            compactLabel: 'label.reboot',
            action: function(args) {
              $.ajax({
                url: createURL("rebootVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.rebootvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            messages: {
              confirm: function(args) {
                return 'message.action.reboot.instance';
              },
              notification: function(args) {
                return 'label.action.reboot.instance';
              }
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },
          snapshot: {
            messages: {
              notification: function(args) {
                return 'label.action.vmsnapshot.create';
              }
            },
            label: 'label.action.vmsnapshot.create',
            addRow: 'false',
            createForm: {
              title: 'label.action.vmsnapshot.create',
              fields: {
                name: {
                  label: 'label.name',
                  isInput: true
                },
                description: {
                  label: 'label.description',
                  isTextarea: true
                },
                snapshotMemory: {
                  label: 'label.vmsnapshot.memory',
                  isBoolean: true,
                  isChecked: false
                }
              }
            },
            action: function(args) {
              var array1 = [];
              array1.push("&snapshotmemory=" + (args.data.snapshotMemory == "on"));
              var displayname = args.data.name;
              if (displayname != null && displayname.length > 0) {
                array1.push("&name=" + todb(displayname));
              }
              var description = args.data.description;
              if (description != null && description.length > 0) {
                array1.push("&description=" + todb(description));
              }
              $.ajax({
                url: createURL("createVMSnapshot&virtualmachineid=" + args.context.instances[0].id + array1.join("")),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.createvmsnapshotresponse.jobid;
                  args.response.success({
                    _custom: {
                      jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                    }
                  });
                }
              });
          
            },
            notification: {
              pool: pollAsyncJobResult
            }
          },          
          destroy: {
            label: 'label.action.destroy.instance',
            compactLabel: 'label.destroy',
            messages: {
              confirm: function(args) {
                return 'message.action.destroy.instance';
              },
              notification: function(args) {
                return 'label.action.destroy.instance';
              }
            },
            action: function(args) {
              $.ajax({
                url: createURL("destroyVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.destroyvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },
          restore: {
            label: 'label.action.restore.instance',
            compactLabel: 'label.restore',
            messages: {
              confirm: function(args) {
                return 'message.action.restore.instance';
              },
              notification: function(args) {
                return 'label.action.restore.instance';
              }
            },
            action: function(args) {
              $.ajax({
                url: createURL("recoverVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var item = json.recovervirtualmachineresponse.virtualmachine;
                  args.response.success({data:item});
                }
              });
            },
            notification: {
              poll: function(args) {
                args.complete({ data: { state: 'Stopped' }});
              }
            }
          },
          reset: {
            label: 'Reset VM',
            messages:{
              confirm:function(args) {
                 return 'Do you want to restore the VM ?';
                },
               notification:function(args) {
                return 'Reset VM';
               }
            },

            action:function(args){
                $.ajax({
                url: createURL("restoreVirtualMachine&virtualmachineid=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var item = json.restorevmresponse;
                  args.response.success({data:item});
                }
              });

            },

           notification: {
              poll: function(args) {
                args.complete({ data: { state: 'Stopped' }});
              }
            }

          },

          changeAffinity: {
            label: 'Change affinity',

            action: {
              custom: cloudStack.uiCustom.affinity({
                tierSelect: function(args) {
                  if ('vpc' in args.context) { //from VPC section
                    args.$tierSelect.show(); //show tier dropdown

                    $.ajax({ //populate tier dropdown
                      url: createURL("listNetworks"),
                      async: false,
                      data: {
                        vpcid: args.context.vpc[0].id,
                        //listAll: true,  //do not pass listAll to listNetworks under VPC
											  domainid: args.context.vpc[0].domainid,
						            account: args.context.vpc[0].account,
                        supportedservices: 'StaticNat'
                      },
                      success: function(json) {
                        var networks = json.listnetworksresponse.network;
                        var items = [{ id: -1, description: 'Please select a tier' }];
                        $(networks).each(function(){
                          items.push({id: this.id, description: this.displaytext});
                        });
                        args.response.success({ data: items });
                      }
                    });
                  }
                  else { //from Guest Network section
                    args.$tierSelect.hide();
                  }

                  args.$tierSelect.change(function() {
                    args.$tierSelect.closest('.list-view').listView('refresh');
                  });
                  args.$tierSelect.closest('.list-view').listView('refresh');
                },

                listView: {
                  listView: {
                    id: 'affinityGroups',
                    fields: {
                      name: { label: 'label.name' },
                      type: { label: 'label.type' }
                    },
                    dataProvider: function(args) {				
                      var data = {
                        domainid: args.context.instances[0].domainid,
                        account: args.context.instances[0].account
                      };                    
											$.ajax({
												url: createURL('listAffinityGroups'),
												data: data,
												async: false, //make it sync to avoid dataProvider() being called twice which produces duplicate data
												success: function(json) {	
                          var items = [];												
													var allAffinityGroups = json.listaffinitygroupsresponse.affinitygroup;
													var previouslySelectedAffinityGroups = args.context.instances[0].affinitygroup;
													if(allAffinityGroups != null) {		
													  for(var i = 0; i < allAffinityGroups.length; i++) {														  
														  var isPreviouslySelected = false;														  
															if(previouslySelectedAffinityGroups != null) {
															  for(var k = 0; k < previouslySelectedAffinityGroups.length; k++) {
																  if(previouslySelectedAffinityGroups[k].id == allAffinityGroups[i].id) {
																	  isPreviouslySelected = true;
																	  break; //break for loop
																	}
																}																
															}												
															items.push($.extend(allAffinityGroups[i], {
															  _isSelected: isPreviouslySelected
															}));	                             													
														}
													}											
													args.response.success({data: items});
												}
											});													
                    }
                  }
                },
                action: function(args) {                  
									var affinityGroupIdArray = [];
									if(args.context.affinityGroups != null) {
									  for(var i = 0; i < args.context.affinityGroups.length; i++) {										  
											if(args.context.affinityGroups[i]._isSelected == true) {
											  affinityGroupIdArray.push(args.context.affinityGroups[i].id);
											}
										}
									}									
									var data = {
									  id: args.context.instances[0].id,
										affinitygroupids: affinityGroupIdArray.join(",")
									};									
									$.ajax({
									  url: createURL('updateVMAffinityGroup'),
										data: data,
										success: function(json) {										  
											var jid = json.updatevirtualmachineresponse.jobid;											
											args.response.success(
												{_custom:
												 {jobId: jid,
													getUpdatedItem: function(json) {													  
														return json.queryasyncjobresultresponse.jobresult.virtualmachine;
													},
													getActionFilter: function() {
														return vmActionfilter;
													}
												 }
												}
											);												
										}
									});			
                }
              })
            },
            messages: {
              notification: function(args) {
                return 'Change affinity';
              }
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },

          edit: {
            label: 'label.edit',
            action: function(args) {
						  var data = {
							  id: args.context.instances[0].id,
							  group: args.data.group,
							  isdynamicallyscalable: (args.data.isdynamicallyscalable=="on"),
								ostypeid: args.data.guestosid
							};
						  
							if(args.data.displayname != args.context.instances[0].displayname) {
							  $.extend(data, {
								  displayName: args.data.displayname
								});							
							}								

              $.ajax({
                url: createURL('updateVirtualMachine'),
                data: data,
                success: function(json) {
                  var item = json.updatevirtualmachineresponse.virtualmachine;
                  args.response.success({data:item});
                }
              });
            }
          },

          attachISO: {
            label: 'label.action.attach.iso',
            createForm: {
              title: 'label.action.attach.iso',             
              fields: {
                iso: {
                  label: 'ISO',
                  select: function(args) {
									  var items = [];
										var map = {};
                    $.ajax({
                      url: createURL("listIsos&isReady=true&isofilter=featured"),
                      dataType: "json",
                      async: false,
                      success: function(json) {
                        var isos = json.listisosresponse.iso;                        
                        $(isos).each(function() {
                          items.push({id: this.id, description: this.displaytext});
													map[this.id] = 1;
                        });                        
                      }
                    });
										$.ajax({
                      url: createURL("listIsos&isReady=true&isofilter=community"),
                      dataType: "json",
                      async: false,
                      success: function(json) {
                        var isos = json.listisosresponse.iso;                        
                        $(isos).each(function() {												  
													if(!(this.id in map)) {
                            items.push({id: this.id, description: this.displaytext});
														map[this.id] = 1;
													}
                        });                        
                      }
                    });
										$.ajax({
                      url: createURL("listIsos&isReady=true&isofilter=selfexecutable"),
                      dataType: "json",
                      async: false,
                      success: function(json) {
                        var isos = json.listisosresponse.iso;                        
                        $(isos).each(function() {												 
													if(!(this.id in map)) {
                            items.push({id: this.id, description: this.displaytext});
														map[this.id] = 1;
													}
                        });                             
                      }
                    });
																				
										args.response.success({data: items});
                  }
                }
              }
            },
            action: function(args) {
              $.ajax({
                url: createURL("attachIso&virtualmachineid=" + args.context.instances[0].id + "&id=" + args.data.iso),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.attachisoresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            messages: {             
              notification: function(args) {
                return 'label.action.attach.iso';
              }
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },

          detachISO: {
            label: 'label.action.detach.iso',
            messages: {
              confirm: function(args) {
                return 'message.detach.iso.confirm';
              },
              notification: function(args) {
                return 'label.action.detach.iso';
              }
            },
            action: function(args) {
              $.ajax({
                url: createURL("detachIso&virtualmachineid=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.detachisoresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },

          resetPassword: {
            label: 'label.action.reset.password',
            messages: {
              confirm: function(args) {
                return 'message.action.instance.reset.password';
              },
              notification: function(args) {
                return 'label.action.reset.password';
              },
              complete: function(args) {
                return 'Password has been reset to ' + args.password;
              }
            },

            preAction: function(args) {
              var jsonObj = args.context.instances[0];
              if (jsonObj.passwordenabled == false) {
                cloudStack.dialog.notice({ message: 'message.reset.password.warning.notPasswordEnabled' });
                return false;
              }
              else if (jsonObj.state != 'Stopped') {
                cloudStack.dialog.notice({ message: 'message.reset.password.warning.notStopped' });
                return false;
              }
              return true;
            },

            action: function(args) {
              $.ajax({
                url: createURL("resetPasswordForVirtualMachine&id=" + args.context.instances[0].id),
                dataType: "json",
                async: true,
                success: function(json) {
                  var jid = json.resetpasswordforvirtualmachineresponse.jobid;
                  args.response.success(
                    {_custom:
                     {jobId: jid,
                      getUpdatedItem: function(json) {
                        return json.queryasyncjobresultresponse.jobresult.virtualmachine;
                      },
                      getActionFilter: function() {
                        return vmActionfilter;
                      }
                     }
                    }
                  );
                }
              });
            },
            notification: {
              poll: pollAsyncJobResult
            }
          },

          createTemplate: {
            label: 'label.create.template',
            messages: {
              confirm: function(args) {
                return 'message.create.template';
              },
              notification: function(args) {
                return 'label.create.template';
              }
            },
            createForm: {
              title: 'label.create.template',
              desc: 'label.create.template',
{'fraction_non_alphanumeric': 0.1045619578592371, 'fraction_numerical': 0.0018989168578242971, 'mean_word_length': 1.0630562868246207, 'pattern_counts': {'":': 10, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6239522', 'n_tokens_mistral': 19810, 'n_tokens_neox': 15345, 'n_words': 2863}