package org.ovirt.engine.core.bll;

import java.util.ArrayList;

import org.ovirt.engine.core.bll.job.ExecutionHandler;
import org.ovirt.engine.core.bll.tasks.SPMAsyncTaskHandler;
import org.ovirt.engine.core.bll.tasks.TaskHandlerCommand;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.AddImageFromScratchParameters;
import org.ovirt.engine.core.common.action.ImportRepoImageParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.asynctasks.AsyncTaskCreationInfo;
import org.ovirt.engine.core.common.asynctasks.AsyncTaskType;
import org.ovirt.engine.core.common.asynctasks.EntityInfo;
import org.ovirt.engine.core.common.businessentities.DiskImage;
import org.ovirt.engine.core.common.businessentities.DiskInterface;
import org.ovirt.engine.core.common.businessentities.StorageDomain;
import org.ovirt.engine.core.common.businessentities.VolumeFormat;
import org.ovirt.engine.core.common.businessentities.VolumeType;
import org.ovirt.engine.core.common.vdscommands.DeleteImageGroupVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.common.vdscommands.VDSReturnValue;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;


public class ImportRepoImageCreateTaskHandler implements SPMAsyncTaskHandler {

    private final TaskHandlerCommand<? extends ImportRepoImageParameters> enclosingCommand;

    private StorageDomain destinationStorageDomain;

    public ImportRepoImageCreateTaskHandler(TaskHandlerCommand<? extends ImportRepoImageParameters> enclosingCommand) {
        this.enclosingCommand = enclosingCommand;
    }

    @Override
    public void execute() {
        if (enclosingCommand.getParameters().getTaskGroupSuccess()) {
            enclosingCommand.getParameters().setImageGroupID(Guid.newGuid());
            enclosingCommand.getParameters().setEntityInfo(
                    new EntityInfo(VdcObjectType.Disk, enclosingCommand.getParameters().getImageGroupID()));

            // Filling in all the remaining fields of the target DiskImage
            DiskImage diskImage = enclosingCommand.getParameters().getDiskImage();
            ArrayList<Guid> storageIds = new ArrayList<>();
            storageIds.add(enclosingCommand.getParameters().getStorageDomainId());
            diskImage.setStorageIds(storageIds);
            diskImage.setStoragePoolId(enclosingCommand.getParameters().getStoragePoolId());
            diskImage.setId(enclosingCommand.getParameters().getImageGroupID());
            diskImage.setDiskInterface(DiskInterface.VirtIO);

            if (diskImage.getVolumeFormat() == VolumeFormat.RAW &&
                    getDestinationStorageDomain().getStorageType().isBlockDomain()) {
                diskImage.setVolumeType(VolumeType.Preallocated);
            } else {
                diskImage.setVolumeType(VolumeType.Sparse);
            }

            VdcReturnValueBase vdcReturnValue =
                    Backend.getInstance().runInternalAction(VdcActionType.AddImageFromScratch,
                            getAddImageFromScratchParameters(),
                            ExecutionHandler.createDefaultContexForTasks(enclosingCommand.getExecutionContext()));

            enclosingCommand.getReturnValue().getVdsmTaskIdList().addAll(vdcReturnValue.getInternalVdsmTaskIdList());

            if (vdcReturnValue.getActionReturnValue() != null) {
                DiskImage newDiskImage = (DiskImage) vdcReturnValue.getActionReturnValue();
                enclosingCommand.getParameters().setDestinationImageId(newDiskImage.getImageId());
                enclosingCommand.getParameters().getDiskImage().setImageId(newDiskImage.getImageId());
            }

            ExecutionHandler.setAsyncJob(enclosingCommand.getExecutionContext(), true);
            enclosingCommand.getReturnValue().setSucceeded(true);
        }
    }

    protected StorageDomain getDestinationStorageDomain() {
        if (destinationStorageDomain == null) {
            destinationStorageDomain = DbFacade.getInstance().getStorageDomainDao().get(
                    enclosingCommand.getParameters().getStorageDomainId());
        }
        return destinationStorageDomain;
    }

    protected AddImageFromScratchParameters getAddImageFromScratchParameters() {
        AddImageFromScratchParameters parameters = new AddImageFromScratchParameters(
                Guid.Empty, null, enclosingCommand.getParameters().getDiskImage());
        parameters.setStoragePoolId(enclosingCommand.getParameters().getStoragePoolId());
        parameters.setStorageDomainId(enclosingCommand.getParameters().getStorageDomainId());
        parameters.setImageGroupID(enclosingCommand.getParameters().getImageGroupID());
        parameters.setQuotaId(enclosingCommand.getParameters().getQuotaId());
        parameters.setParentCommand(VdcActionType.ImportRepoImage);
        parameters.setParentParameters(enclosingCommand.getParameters());
        return parameters;
    }

    @Override
    public void endSuccessfully() {
        enclosingCommand.getReturnValue().setSucceeded(true);
    }

    @Override
    public void endWithFailure() {
        deleteImageGroup();
        enclosingCommand.getReturnValue().setSucceeded(true);
    }

    @Override
    public void compensate() {
        deleteImageGroup();
    }

    protected void deleteImageGroup() {
        VDSReturnValue vdsReturnValue =
                Backend.getInstance().getResourceManager().RunVdsCommand(VDSCommandType.DeleteImageGroup,
                    new DeleteImageGroupVDSCommandParameters(
                            enclosingCommand.getParameters().getStoragePoolId(),
                            enclosingCommand.getParameters().getStorageDomainId(),
                            enclosingCommand.getParameters().getImageGroupID(),
                            true, true));

        AsyncTaskCreationInfo taskCreationInfo = vdsReturnValue.getCreationInfo();
        enclosingCommand.getReturnValue().getInternalVdsmTaskIdList().add(enclosingCommand.createTask(
                Guid.Empty,
                taskCreationInfo,
                enclosingCommand.getActionType(),
                VdcObjectType.Disk,
                new Guid[] { enclosingCommand.getParameters().getImageGroupID() })
        );

        Guid vdsmTaskId = taskCreationInfo.getVdsmTaskId();
        enclosingCommand.getReturnValue().getVdsmTaskIdList().add(vdsmTaskId);
    }

    @Override
    public AsyncTaskType getTaskType() {
        return null; // No implementation - handled by the command
    }

    @Override
    public AsyncTaskType getRevertTaskType() {
        return null; // No implementation - handled by the command
    }

}

@@ -419,32 +419,97 @@
 mageParameters;%0A
+import org.ovirt.engine.core.common.action.RemoveDiskParameters;%0A
 import org.ovirt
@@ -617,78 +617,8 @@
 se;%0A
-import org.ovirt.engine.core.common.asynctasks.AsyncTaskCreationInfo;%0A
 impo
@@ -1070,222 +1070,8 @@
 pe;%0A
-import org.ovirt.engine.core.common.vdscommands.DeleteImageGroupVDSCommandParameters;%0Aimport org.ovirt.engine.core.common.vdscommands.VDSCommandType;%0Aimport org.ovirt.engine.core.common.vdscommands.VDSReturnValue;%0A
 impo
@@ -5094,36 +5094,8 @@
 ) %7B%0A
-        deleteImageGroup();%0A
     
@@ -5216,86 +5216,11 @@
     
-deleteImageGroup();%0A    %7D%0A%0A    protected void deleteImageGroup() %7B%0A        VDS
+Vdc
 Retu
@@ -5226,20 +5226,24 @@
 urnValue
+Base
  vd
-s
+c
 ReturnVa
@@ -5247,32 +5247,16 @@
 nValue =
-%0A               
  Backend
@@ -5274,505 +5274,144 @@
 e().
-getResourceManager().RunVdsCommand(VDSCommandType.DeleteImageGroup,%0A                    new DeleteImageGroupVDSCommandParameters(%0A                            enclosingCommand.getParameters().getStoragePoolId(),%0A                            enclosingCommand.getParameters().getStorageDomainId(),%0A                            enclosingCommand.getParameters().getImageGroupID(),%0A                            true, true));%0A%0A        AsyncTaskCreationInfo taskCreationInfo = vdsReturnValue.getCreationInfo(
+runInternalAction(VdcActionType.RemoveDisk,%0A                new RemoveDiskParameters(enclosingCommand.getParameters().getImageGroupID())
 );%0A 
@@ -5450,32 +5450,24 @@
 nValue().get
-Internal
 VdsmTaskIdLi
@@ -5478,386 +5478,38 @@
 .add
-(enclosingCommand.createTask(%0A                Guid.Empty,%0A                taskCreationInfo,%0A                enclosingCommand.getActionType(),%0A                VdcObjectType.Disk,%0A                new Guid%5B%5D %7B enclosingCommand.getParameters().getImageGroupID() %7D)%0A        );%0A%0A        Guid vdsmTaskId = taskCreationInfo.getVdsmTaskId();%0A        enclosingCommand.getRetu
+All(vdcReturnValue.getInte
 rn
-V
 al
-ue().get
 Vdsm
@@ -5524,23 +5524,8 @@
 st()
-.add(vdsmTaskId
 );%0A 
@@ -5739,59 +5739,34 @@
 urn 
-null; // No implementation - handled by the command
+AsyncTaskType.deleteImage;
 %0A   

fix task revert for ImportRepoImageCommand