package org.ovirt.engine.core.bll;

import java.util.ArrayList;
import java.util.List;

import org.ovirt.engine.core.bll.utils.VmDeviceUtils;
import org.ovirt.engine.core.common.action.UpdateVmDiskParameters;
import org.ovirt.engine.core.common.businessentities.DiskImage;
import org.ovirt.engine.core.common.businessentities.VMStatus;
import org.ovirt.engine.core.common.businessentities.VmDevice;
import org.ovirt.engine.core.common.businessentities.VmDeviceId;
import org.ovirt.engine.core.common.utils.VmDeviceType;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.dal.VdcBllMessages;

public class AttachDiskToVmCommand<T extends UpdateVmDiskParameters> extends AbstractDiskVmCommand<T> {

    private static final long serialVersionUID = -1686587389737849288L;
    private DiskImage diskImage;

    public AttachDiskToVmCommand(T parameters) {
        super(parameters);
        if (getParameters().getDiskInfo().getPlugged() == null) {
            getParameters().getDiskInfo().setPlugged(false);
        }
    }

    @Override
    protected boolean canDoAction() {
        boolean retValue = isVmExist() && isVmUpOrDown();
        diskImage = getDiskImageDao().get(getParameters().getImageId());
        if (retValue && diskImage == null) {
            retValue = false;
            addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_VM_IMAGE_DOES_NOT_EXIST);
        }
        retValue =
                retValue && isDiskCanBeAddedToVm(getParameters().getDiskInfo())
                        && isDiskPassPCIAndIDELimit(getParameters().getDiskInfo());
        if (retValue && getVmDeviceDao().exists(new VmDeviceId(diskImage.getimage_group_id(), getVmId()))) {
            retValue = false;
            addCanDoActionMessage(VdcBllMessages.ACTION_TYPE_FAILED_DISK_ALREADY_ATTACHED);
        }
        if (retValue && Boolean.TRUE.equals(getParameters().getDiskInfo().getPlugged())
                && getVm().getstatus() != VMStatus.Down) {
            retValue = isOSSupportingHotPlug() && isHotPlugSupported()
                            && isInterfaceSupportedForPlugUnPlug(getParameters().getDiskInfo());
        }

        return retValue;
    }

    @Override
    protected void ExecuteVmCommand() {
        final VmDevice vmDevice =
                new VmDevice(new VmDeviceId(diskImage.getId(), getVmId()),
                        VmDeviceType.DISK.getName(),
                        VmDeviceType.DISK.getName(),
                        "",
                        0,
                        null,
                        true,
                        Boolean.TRUE.equals(getParameters().getDiskInfo().getPlugged()),
                        false);
        diskImage.setinternal_drive_mapping(getParameters().getDiskInfo().getinternal_drive_mapping());
        diskImage.setboot(getParameters().getDiskInfo().getboot());
        diskImage.setDiskInterface(getParameters().getDiskInfo().getDiskInterface());
        getDiskImageDao().update(diskImage);
        getVmDeviceDao().save(vmDevice);
        // update cached image
        List<DiskImage> imageList = new ArrayList<DiskImage>();
        imageList.add(diskImage);
        VmHandler.updateDisksForVm(getVm(), imageList);
        // update vm device boot order
        VmDeviceUtils.updateBootOrderInVmDevice(getVm().getStaticData());
        if (Boolean.TRUE.equals(getParameters().getDiskInfo().getPlugged()) && getVm().getstatus() != VMStatus.Down) {
            performPlugCommnad(VDSCommandType.HotPlugDisk, diskImage, vmDevice);
        }
        setSucceeded(true);
    }

   @Override
    protected void setActionMessageParameters() {
        addCanDoActionMessage(VdcBllMessages.VAR__ACTION__ATTACH_ACTION_TO);
        addCanDoActionMessage(VdcBllMessages.VAR__TYPE__VM_DISK);
    }
}

@@ -29,16 +29,17 @@
 e.bll;%0A%0A
+%0A
 import j
@@ -136,16 +136,122 @@
 eUtils;%0A
+import org.ovirt.engine.core.common.PermissionSubject;%0Aimport org.ovirt.engine.core.common.VdcObjectType;%0A
 import o
@@ -309,16 +309,82 @@
 meters;%0A
+import org.ovirt.engine.core.common.businessentities.ActionGroup;%0A
 import o
@@ -746,24 +746,66 @@
 ommandType;%0A
+import org.ovirt.engine.core.compat.Guid;%0A
 import org.o
@@ -1051,16 +1051,70 @@
 skImage;
+%0A    private List%3CPermissionSubject%3E permsList = null;
 %0A%0A    pu
@@ -1316,24 +1316,97 @@
 ;%0A        %7D%0A
+        diskImage = getDiskImageDao().get(getParameters().getImageId());%0A
     %7D%0A%0A    @
@@ -1514,81 +1514,8 @@
 ();%0A
-        diskImage = getDiskImageDao().get(getParameters().getImageId());%0A
     
@@ -4075,10 +4075,408 @@
 ;%0A    %7D%0A
+%0A    @Override%0A   public List%3CPermissionSubject%3E getPermissionCheckSubjects()%7B%0A       if (permsList == null) %7B%0A           permsList = super.getPermissionCheckSubjects();%0A            Guid diskId = diskImage == null ? null : diskImage.getimage_group_id();%0A            permsList.add(new PermissionSubject(diskId, VdcObjectType.Disk, ActionGroup.ATTACH_DISK));%0A       %7D%0A        return permsList;%0A   %7D%0A%0A
 %7D%0A

Check permissions on disk when attaching disk to VM