// 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.
package com.cloud.vm;

import com.cloud.storage.Snapshot;
import com.cloud.storage.Volume;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.cloud.deploy.DeploymentPlan;
import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
import org.apache.cloudstack.api.command.user.vm.CreateVMFromBackupCmd;
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
import org.apache.cloudstack.api.command.user.vm.RebootVMCmd;
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
import org.apache.cloudstack.api.command.user.vm.ResetVMUserDataCmd;
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateDefaultNicForVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVMCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVmNicCmd;
import org.apache.cloudstack.api.command.user.vm.UpdateVmNicIpCmd;
import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;

import com.cloud.dc.DataCenter;
import com.cloud.deploy.DeploymentPlanner;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ManagementServerException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.exception.VirtualMachineMigrationException;
import com.cloud.host.Host;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network.IpAddresses;
import com.cloud.offering.DiskOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.storage.StoragePool;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
import com.cloud.utils.Pair;
import com.cloud.utils.exception.ExecutionException;

public interface UserVmService {


    /**
     * Destroys one virtual machine
     *
     * @param cmd the API Command Object containg the parameters to use for this service action
     * @throws ConcurrentOperationException
     * @throws ResourceUnavailableException
     */
    UserVm destroyVm(DestroyVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException;

    /**
     * Destroys one virtual machine
     *
     * @param vmId
     *            the id of the virtual machine.
     * @param expunge
     *            indicates if vm should be expunged
     * @throws ConcurrentOperationException
     * @throws ResourceUnavailableException
     */
    UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableException, ConcurrentOperationException;

    /**
     * Resets the password of a virtual machine.
     *
     * @param cmd
     *            - the command specifying vmId, password
     * @return the VM if reset worked successfully, null otherwise
     */
    UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws ResourceUnavailableException, InsufficientCapacityException;

    /**
     * Resets the SSH Key of a virtual machine.
     *
     * @param cmd
     *            - the command specifying vmId, Keypair name
     * @return the VM if reset worked successfully, null otherwise
     */
    UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;

    UserVm resetVMUserData(ResetVMUserDataCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;

    UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, ExecutionException, ConcurrentOperationException, ResourceUnavailableException,
        InsufficientCapacityException, ResourceAllocationException;

    UserVm rebootVirtualMachine(RebootVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException;

    void startVirtualMachine(UserVm vm, DeploymentPlan plan) throws OperationTimedoutException, ResourceUnavailableException, InsufficientCapacityException;

    void startVirtualMachineForHA(VirtualMachine vm, Map<VirtualMachineProfile.Param, Object> params,
          DeploymentPlanner planner) throws InsufficientCapacityException, ResourceUnavailableException,
            ConcurrentOperationException, OperationTimedoutException;

    UserVm updateVirtualMachine(UpdateVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;

    /**
     * Adds a NIC on the given network to the virtual machine
     * @param cmd the command object that defines the vm and the given network
     * @return the vm object if successful, null otherwise
     */
    UserVm addNicToVirtualMachine(AddNicToVMCmd cmd);

    /**
     * Removes a NIC on the given network from the virtual machine
     * @param cmd the command object that defines the vm and the given network
     * @return the vm object if successful, null otherwise
     */
    UserVm removeNicFromVirtualMachine(RemoveNicFromVMCmd cmd);

    /**
     * Updates default Nic to the given network for given virtual machine
     * @param cmd the command object that defines the vm and the given network
     * @return the vm object if successful, null otherwise
     */
    UserVm updateDefaultNicForVirtualMachine(UpdateDefaultNicForVMCmd cmd);

    /**
     * Updated the ip address on the given NIC to the virtual machine
     * @param cmd the command object that defines the ip address and the given nic
     * @return the vm object if successful, null otherwise
     */
    UserVm updateNicIpForVirtualMachine(UpdateVmNicIpCmd cmd);

    UserVm updateVirtualMachineNic(UpdateVmNicCmd cmd);

    UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException;

    /**
     * Creates a Basic Zone User VM in the database and returns the VM to the
     * caller.
     *
     * @param zone
     *            - availability zone for the virtual machine
     * @param serviceOffering
     *            - the service offering for the virtual machine
     * @param template
     *            - the template for the virtual machine
     * @param securityGroupIdList
     *            - comma separated list of security groups id that going to be
     *            applied to the virtual machine
     * @param hostName
     *            - host name for the virtual machine
     * @param displayName
     *            - an optional user generated name for the virtual machine
     * @param diskOfferingId
     *            - the ID of the disk offering for the virtual machine. If the
     *            template is of ISO format, the diskOfferingId is for the root
     *            disk volume. Otherwise this parameter is used to indicate the
     *            offering for the data disk volume. If the templateId parameter
     *            passed is from a Template object, the diskOfferingId refers to
     *            a DATA Disk Volume created. If the templateId parameter passed
     *            is from an ISO object, the diskOfferingId refers to a ROOT
     *            Disk Volume created
     * @param diskSize
     *            - the arbitrary size for the DATADISK volume. Mutually
     *            exclusive with diskOfferingId
     * @param group
     *            - an optional group for the virtual machine
     * @param hypervisor
     *            - the hypervisor on which to deploy the virtual machine
     * @param userData
     *            - an optional binary data that can be sent to the virtual
     *            machine upon a successful deployment. This binary data must be
     *            base64 encoded before adding it to the request. Currently only
     *            HTTP GET is supported. Using HTTP GET (via querystring), you
     *            can send up to 2KB of data after base64 encoding
     * @param userDataId
     * @param userDataDetails
     * @param requestedIps
     *            TODO
     * @param defaultIp
     *            TODO
     * @param displayVm
     *            - Boolean flag whether to the display the vm to the end user or not
     * @param affinityGroupIdList
     * @param customId
     * @param dhcpOptionMap
     *           - Maps the dhcp option code and the dhcp value to the network uuid
     * @param dataDiskTemplateToDiskOfferingMap
     *            - Datadisk template to Disk offering Map
     *             an optional parameter that creates additional data disks for the virtual machine
     *             For each of the templates in the map, a data disk will be created from the corresponding
     *             disk offering obtained from the map
     *
     * @return UserVm object if successful.
     * @throws InsufficientCapacityException
     *             if there is insufficient capacity to deploy the VM.
     * @throws ConcurrentOperationException
     *             if there are multiple users working on the same VM or in the
     *             same environment.
     * @throws ResourceUnavailableException
     *             if the resources required to deploy the VM is not currently
     *             available.
     */
    UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList,
                                                  Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
                                                  String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
                                                  List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
                                                  Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
                                                  Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, Volume volume, Snapshot snapshot) throws InsufficientCapacityException,
        ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;

    /**
     * Creates a User VM in Advanced Zone (Security Group feature is enabled) in
     * the database and returns the VM to the caller.
     *
     * @param zone
     *            - availability zone for the virtual machine
     * @param serviceOffering
     *            - the service offering for the virtual machine
     * @param template
     *            - the template for the virtual machine
     * @param networkIdList
     *            - list of network ids used by virtual machine
     * @param securityGroupIdList
     *            - comma separated list of security groups id that going to be
     *            applied to the virtual machine
     * @param hostName
     *            - host name for the virtual machine
     * @param displayName
     *            - an optional user generated name for the virtual machine
     * @param diskOfferingId
     *            - the ID of the disk offering for the virtual machine. If the
     *            template is of ISO format, the diskOfferingId is for the root
     *            disk volume. Otherwise this parameter is used to indicate the
     *            offering for the data disk volume. If the templateId parameter
     *            passed is from a Template object, the diskOfferingId refers to
     *            a DATA Disk Volume created. If the templateId parameter passed
     *            is from an ISO object, the diskOfferingId refers to a ROOT
     *            Disk Volume created
     * @param diskSize
     *            - the arbitrary size for the DATADISK volume. Mutually
     *            exclusive with diskOfferingId
     * @param group
     *            - an optional group for the virtual machine
     * @param hypervisor
     *            - the hypervisor on which to deploy the virtual machine
     * @param userData
     *            - an optional binary data that can be sent to the virtual
     *            machine upon a successful deployment. This binary data must be
     *            base64 encoded before adding it to the request. Currently only
     *            HTTP GET is supported. Using HTTP GET (via querystring), you
     *            can send up to 2KB of data after base64 encoding
     * @param userDataId
     * @param userDataDetails
     * @param requestedIps
     *            TODO
     * @param defaultIps
     *            TODO
     * @param displayVm
     *            - Boolean flag whether to the display the vm to the end user or not
     * @param affinityGroupIdList
     * @param customId
     * @param dhcpOptionMap
     *             - Maps the dhcp option code and the dhcp value to the network uuid
     * @param dataDiskTemplateToDiskOfferingMap
     *            - Datadisk template to Disk offering Map
     *             an optional parameter that creates additional data disks for the virtual machine
     *             For each of the templates in the map, a data disk will be created from the corresponding
     *             disk offering obtained from the map
     * @return UserVm object if successful.
     *
     * @throws InsufficientCapacityException
     *             if there is insufficient capacity to deploy the VM.
     * @throws ConcurrentOperationException
     *             if there are multiple users working on the same VM or in the
     *             same environment.
     * @throws ResourceUnavailableException
     *             if the resources required to deploy the VM is not currently
     *             available.
     */
    UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
                                                     List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, String group, HypervisorType hypervisor,
                                                     HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
                                                     List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
                                                     Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, String vmType, Volume volume, Snapshot snapshot) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;

    /**
     * Creates a User VM in Advanced Zone (Security Group feature is disabled)
     * in the database and returns the VM to the caller.
     *
     * @param zone
     *            - availability zone for the virtual machine
     * @param serviceOffering
     *            - the service offering for the virtual machine
     * @param template
     *            - the template for the virtual machine
     * @param networkIdList
     *            - list of network ids used by virtual machine
     * @param hostName
     *            - host name for the virtual machine
     * @param displayName
     *            - an optional user generated name for the virtual machine
     * @param diskOfferingId
     *            - the ID of the disk offering for the virtual machine. If the
     *            template is of ISO format, the diskOfferingId is for the root
     *            disk volume. Otherwise this parameter is used to indicate the
     *            offering for the data disk volume. If the templateId parameter
     *            passed is from a Template object, the diskOfferingId refers to
     *            a DATA Disk Volume created. If the templateId parameter passed
     *            is from an ISO object, the diskOfferingId refers to a ROOT
     *            Disk Volume created
     * @param diskSize
     *            - the arbitrary size for the DATADISK volume. Mutually
     *            exclusive with diskOfferingId
     * @param group
     *            - an optional group for the virtual machine
     * @param hypervisor
     *            - the hypervisor on which to deploy the virtual machine
     * @param userData
     *            - an optional binary data that can be sent to the virtual
     *            machine upon a successful deployment. This binary data must be
     *            base64 encoded before adding it to the request. Currently only
     *            HTTP GET is supported. Using HTTP GET (via querystring), you
     *            can send up to 2KB of data after base64 encoding
     * @param userDataId
     * @param userDataDetails
     * @param requestedIps
     *            TODO
     * @param defaultIps
     *            TODO
     * @param displayVm
     *            - Boolean flag whether to the display the vm to the end user or not
     * @param affinityGroupIdList
     * @param customId
     * @param dhcpOptionMap
     *             - Map that maps the DhcpOption code and their value on the Network uuid
     * @param dataDiskTemplateToDiskOfferingMap
     *            - Datadisk template to Disk offering Map
     *             an optional parameter that creates additional data disks for the virtual machine
     *             For each of the templates in the map, a data disk will be created from the corresponding
     *             disk offering obtained from the map
     * @return UserVm object if successful.
     *
     * @throws InsufficientCapacityException
     *             if there is insufficient capacity to deploy the VM.
     * @throws ConcurrentOperationException
     *             if there are multiple users working on the same VM or in the
     *             same environment.
     * @throws ResourceUnavailableException
     *             if the resources required to deploy the VM is not currently
     *             available.
     */
    UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner,
                                        String hostName, String displayName, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
                                        Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
                                        Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
                                        Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId, Volume volume, Snapshot snapshot)

        throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;

    /**
     * Starts the virtual machine created from createVirtualMachine.
     *
     * @param cmd
     *            Command to deploy.
     * @return UserVm object if successful.
     * @throws InsufficientCapacityException
     *             if there is insufficient capacity to deploy the VM.
     * @throws ConcurrentOperationException
     *             if there are multiple users working on the same VM.
     * @throws ResourceUnavailableException
     *             if the resources required the deploy the VM is not currently available.
     */
    UserVm startVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException;

    /**
     * Creates a vm group.
     *
     * @param cmd The command specifying domain ID, account name, group name, and project ID
     */
    InstanceGroup createVmGroup(CreateVMGroupCmd cmd);

    boolean deleteVmGroup(DeleteVMGroupCmd cmd);

    /**
     * upgrade the service offering of the virtual machine
     *
     * @param cmd
     *            - the command specifying vmId and new serviceOfferingId
     * @return the vm
     * @throws ResourceAllocationException
     */
    UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) throws ResourceAllocationException;

    UserVm stopVirtualMachine(long vmId, boolean forced) throws ConcurrentOperationException;

    void deletePrivateTemplateRecord(Long templateId);

    HypervisorType getHypervisorTypeOfUserVM(long vmid);

    UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException,
        StorageUnavailableException, ResourceAllocationException;

    /**
     * This API is mostly to trigger VM.CREATE event for deployVirtualMachine with startvm=false, because there is no code in "execute" part of VM creation.
     * However, it can be used for additional VM customization in the future.
     * @param vmId - Virtual Machine Id
     * @return - Virtual Machine
     */
    UserVm finalizeCreateVirtualMachine(long vmId);

    UserVm getUserVm(long vmId);

    VirtualMachine getVm(long vmId);

    /**
     * Migrate the given VM to the destination host provided. The API returns the migrated VM if migration succeeds.
     * Only Root Admin can migrate a VM.
     *
     * @param vmId The ID of the VM to be migrated
     * @param destinationHost The destination host to where the VM will be migrated
     *
     * @return VirtualMachine migrated VM
     * @throws ManagementServerException
     *             in case we get error finding the VM or host or access errors or other internal errors.
     * @throws ConcurrentOperationException
     *             if there are multiple users working on the same VM.
     * @throws ResourceUnavailableException
     *             if the destination host to migrate the VM is not currently available.
     * @throws VirtualMachineMigrationException
     *             if the VM to be migrated is not in Running state
     */
    VirtualMachine migrateVirtualMachine(Long vmId, Host destinationHost) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
        VirtualMachineMigrationException;

    /**
     * Migrate the given VM with its volumes to the destination host. The API returns the migrated VM if it succeeds.
     * Only root admin can migrate a VM.
     *
     * @param vmId The ID of the VM to be migrated
     * @param destinationHost The destination host to where the VM will be migrated
     * @param volumeToPool A map of volume to which pool it should be migrated
     *
     * @return VirtualMachine migrated VM
     * @throws ManagementServerException
     *             in case we get error finding the VM or host or access errors or other internal errors.
     * @throws ConcurrentOperationException
     *             if there are multiple users working on the same VM.
     * @throws ResourceUnavailableException
     *             if the destination host to migrate the VM is not currently available.
     * @throws VirtualMachineMigrationException
     *             if the VM to be migrated is not in Running state
     */
    VirtualMachine migrateVirtualMachineWithVolume(Long vmId, Host destinationHost, Map<String, String> volumeToPool) throws ResourceUnavailableException,
        ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException;

    UserVm moveVmToUser(AssignVMCmd moveUserVMCmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException,
        InsufficientCapacityException;

    VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool);

    VirtualMachine vmStorageMigration(Long vmId, Map<String, String> volumeToPool);

    UserVm restoreVM(RestoreVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ResourceAllocationException;

    UserVm restoreVirtualMachine(Account caller, long vmId, Long newTemplateId, Long rootDiskOfferingId, boolean expunge, Map<String, String> details) throws InsufficientCapacityException, ResourceUnavailableException;

    UserVm upgradeVirtualMachine(ScaleVMCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException,
        VirtualMachineMigrationException;

    UserVm expungeVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException;

    /**
     * Finds and returns an encrypted password for a VM.
     *
     * @param  vmId
     * @return Base64 encoded userdata
     */
    String getVmUserData(long vmId);

    /**
     * determine whether the uservm should be visible to the end user
     * @return  value of the display flag
     */
    public boolean isDisplayResourceEnabled(Long vmId);

    void collectVmDiskStatistics(UserVm userVm);

    void collectVmNetworkStatistics (UserVm userVm);

    /**
     * Import VM into CloudStack
     * @param zone importing zone
     * @param host importing host
     * @param template template for the imported VM
     * @param instanceNameInternal set to null to CloudStack to autogenerate from the next available VM ID on database
     * @param displayName display name for the imported VM
     * @param owner owner of the imported VM
     * @param userData user data for the imported VM
     * @param caller caller account
     * @param isDisplayVm true to display the imported VM
     * @param keyboard keyboard distribution for the imported VM
     * @param accountId account ID
     * @param userId user ID
     * @param serviceOffering service offering for the imported VM
     * @param sshPublicKey ssh key for the imported VM
     * @param guestOsId guest OS ID for the imported VM (if not passed, then the guest OS of the template will be used)
     * @param hostName the name for the imported VM
     * @param hypervisorType hypervisor type for the imported VM
     * @param customParameters details for the imported VM
     * @param powerState power state of the imported VM
     * @param networkNicMap network to nic mapping
     * @return the imported VM
     * @throws InsufficientCapacityException in case of errors
     */
    UserVm importVM(final DataCenter zone, final Host host, final VirtualMachineTemplate template, final String instanceNameInternal, final String displayName, final Account owner, final String userData, final Account caller, final Boolean isDisplayVm, final String keyboard,
                    final long accountId, final long userId, final ServiceOffering serviceOffering, final String sshPublicKey, final Long guestOsId,
                    final String hostName, final HypervisorType hypervisorType, final Map<String, String> customParameters,
                    final VirtualMachine.PowerState powerState, final LinkedHashMap<String, List<NicProfile>> networkNicMap) throws InsufficientCapacityException;

    /**
     * Unmanage a guest VM from CloudStack
     *
     * @return (true if successful, false if not, hostUuid) if the VM is successfully unmanaged.
     */
    Pair<Boolean, String> unmanageUserVM(Long vmId, Long targetHostId);

    UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws InsufficientCapacityException, ResourceAllocationException, ResourceUnavailableException;

    UserVm restoreVMFromBackup(CreateVMFromBackupCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;
}
