package org.ovirt.engine.core.bll;

import java.io.File;

import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.bll.validator.LocalizedVmStatus;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.action.ChangeDiskCommandParameters;
import org.ovirt.engine.core.common.errors.VdcBllMessages;
import org.ovirt.engine.core.common.utils.ValidationUtils;
import org.ovirt.engine.core.common.vdscommands.ChangeDiskVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;

public class ChangeDiskCommand<T extends ChangeDiskCommandParameters> extends VmOperationCommandBase<T> {
    private String cdImagePath;

    public ChangeDiskCommand(T parameters) {
        super(parameters);
    }

    public String getDiskName() {
        return new File(cdImagePath).getName();
    }

    @Override
    protected void setActionMessageParameters() {
        addCanDoActionMessage(VdcBllMessages.VAR__ACTION__CHANGE_CD);
        addCanDoActionMessage(VdcBllMessages.VAR__TYPE__VM);
    }

    @Override
    protected boolean canDoAction() {
        boolean retValue = true;
        if (getVm() == null) {
            addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_VM_NOT_EXIST);
            retValue = false;
        }

        if (retValue && !canRunActionOnNonManagedVm()) {
            retValue = false;
        } else {
            cdImagePath = ImagesHandler.cdPathWindowsToLinux(getParameters().getCdImagePath(), getVm().getStoragePoolId(), getVm().getRunOnVds());
        }

        if (retValue && !getVm().isRunningOrPaused()) {
            setSucceeded(false);
            retValue = false;
            addCanDoActionMessage(VdcBllMessages.VAR__TYPE__VM);

            // An empty 'cdImagePath' means eject CD
            if (!StringUtils.isEmpty(cdImagePath)) {
                addCanDoActionMessage(VdcBllMessages.VAR__ACTION__CHANGE_CD);
            } else {
                addCanDoActionMessage(VdcBllMessages.VAR__ACTION__EJECT_CD);
            }
            failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_VM_STATUS_ILLEGAL, LocalizedVmStatus.from(getVm().getStatus()));
        } else if ((IsoDomainListSyncronizer.getInstance().findActiveISODomain(getVm().getStoragePoolId()) == null)
                && !StringUtils.isEmpty(cdImagePath)) {
            addCanDoActionMessage(VdcBllMessages.VAR__ACTION__CHANGE_CD);
            addCanDoActionMessage(VdcBllMessages.VM_CANNOT_WITHOUT_ACTIVE_STORAGE_DOMAIN_ISO);
            setSucceeded(false);
            retValue = false;
        } else if (StringUtils.isNotEmpty(cdImagePath) && !cdImagePath.endsWith(ValidationUtils.ISO_SUFFIX)) {
            addCanDoActionMessage(VdcBllMessages.VAR__ACTION__CHANGE_CD);
            addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_INVALID_CDROM_DISK_FORMAT);
            setSucceeded(false);
            retValue = false;
        }
        return retValue;
    }

    @Override
    protected void perform() {
        setActionReturnValue(runVdsCommand(VDSCommandType.ChangeDisk,
                        new ChangeDiskVDSCommandParameters(getVdsId(), getVm().getId(), cdImagePath))
                .getReturnValue());
        VmHandler.updateCurrentCd(getVdsId(), getVm(), getParameters().getCdImagePath());
        setSucceeded(true);

    }

    @Override
    public AuditLogType getAuditLogTypeValue() {
        return getSucceeded() ? "".equals(cdImagePath) ? AuditLogType.USER_EJECT_VM_DISK
                : AuditLogType.USER_CHANGE_DISK_VM : AuditLogType.USER_FAILED_CHANGE_DISK_VM;
    }
}

@@ -1107,41 +1107,8 @@
 ) %7B%0A
-        boolean retValue = true;%0A
     
@@ -1138,35 +1138,43 @@
 ) %7B%0A            
-add
+return fail
 CanDoActionMessa
@@ -1160,39 +1160,32 @@
  failCanDoAction
-Message
 (VdcBllMessages.
@@ -1222,38 +1222,8 @@
 T);%0A
-            retValue = false;%0A
     
@@ -1241,28 +1241,16 @@
     if (
-retValue && 
 !canRunA
@@ -1281,39 +1281,35 @@
 %0A            ret
-Value =
+urn
  false;%0A        
@@ -1305,36 +1305,26 @@
 e;%0A        %7D
- else %7B%0A    
+%0A%0A
         cdIm
@@ -1337,138 +1337,41 @@
 h = 
-ImagesHandler.cdPathWindowsToLinux(getParameters().getCdImagePath(), getVm().getStoragePoolId(), getVm().getRunOnVds());%0A        %7D
+getParameters().getCdImagePath();
 %0A%0A  
@@ -1384,20 +1384,8 @@
 if (
-retValue && 
 !get
@@ -1416,71 +1416,8 @@
 ) %7B%0A
-            setSucceeded(false);%0A            retValue = false;%0A
     
@@ -1786,16 +1786,23 @@
         
+return 
 failCanD
@@ -1913,29 +1913,33 @@
 );%0A        %7D
- else
+%0A%0A       
  if ((IsoDom
@@ -2162,35 +2162,43 @@
 D);%0A            
-add
+return fail
 CanDoActionMessa
@@ -2184,39 +2184,32 @@
  failCanDoAction
-Message
 (VdcBllMessages.
@@ -2266,62 +2266,10 @@
     
-    setSucceeded(false);%0A            retValue = false;
+%7D%0A
 %0A   
@@ -2273,23 +2273,16 @@
         
-%7D else 
 if (Stri
@@ -2447,35 +2447,43 @@
 D);%0A            
-add
+return fail
 CanDoActionMessa
@@ -2469,39 +2469,32 @@
  failCanDoAction
-Message
 (VdcBllMessages.
@@ -2552,72 +2552,10 @@
     
-    setSucceeded(false);%0A            retValue = false;%0A        
 %7D
+%0A
 %0A   
@@ -2570,14 +2570,10 @@
 urn 
+t
 r
-etVal
 ue;%0A
@@ -2620,24 +2620,167 @@
 perform() %7B%0A
+        cdImagePath = ImagesHandler.cdPathWindowsToLinux(getParameters().getCdImagePath(), getVm().getStoragePoolId(), getVm().getRunOnVds());%0A
         setA

Fix NPE on ChangeCD with 'Down' VM