package org.ovirt.engine.core.bll.storage;

import com.woorea.openstack.base.client.OpenStackResponseException;
import com.woorea.openstack.cinder.model.Volume;
import com.woorea.openstack.cinder.model.VolumeForCreate;
import org.ovirt.engine.core.bll.provider.storage.OpenStackVolumeProviderProxy;
import org.ovirt.engine.core.common.businessentities.storage.CinderDisk;
import org.ovirt.engine.core.common.businessentities.storage.CinderVolumeStatus;
import org.ovirt.engine.core.common.businessentities.storage.ImageStatus;
import org.ovirt.engine.core.common.errors.VdcBllErrors;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase;

import java.util.ArrayList;
import java.util.concurrent.Callable;

public class CinderBroker extends AuditLogableBase {

    private OpenStackVolumeProviderProxy proxy;
    private ArrayList<String> executeFailedMessages;

    public CinderBroker(Guid storageDomainId, ArrayList<String> executeFailedMessages) {
        this.proxy = getVolumeProviderProxy(storageDomainId);
        this.executeFailedMessages = executeFailedMessages;
    }

    private <T> T execute(Callable<T> callable) {
        try {
            return callable.call();
        } catch (OpenStackResponseException e) {
            executeFailedMessages.add(VdcBllErrors.CINDER_ERROR.name());
            executeFailedMessages.add(String.format("$cinderException %1$s", e.getMessage()));
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public String createDisk(final CinderDisk cinderDisk) {
        return execute(new Callable<String>() {
            @Override
            public String call() {
                VolumeForCreate cinderVolume = new VolumeForCreate();
                cinderVolume.setName(cinderDisk.getDiskAlias());
                cinderVolume.setDescription(cinderDisk.getDiskDescription());
                cinderVolume.setSize((int) (cinderDisk.getSizeInGigabytes()));
                cinderVolume.setVolumeType(cinderDisk.getCinderVolumeType());
                return proxy.createVolume(cinderVolume);
            }
        });
    }

    public ImageStatus getDiskStatus(final Guid id) {
        return execute(new Callable<ImageStatus>() {
            @Override
            public ImageStatus call() {
                Volume volume = proxy.getVolumeById(id.toString());
                CinderVolumeStatus cinderVolumeStatus = CinderVolumeStatus.forValue(volume.getStatus());
                return mapCinderVolumeStatusToImageStatus(cinderVolumeStatus);
            }
        });
    }

    protected static ImageStatus mapCinderVolumeStatusToImageStatus(CinderVolumeStatus cinderVolumeStatus) {
        switch (cinderVolumeStatus) {
            case Available:
                return ImageStatus.OK;
            case Creating:
            case Deleting:
            case Extending:
                return ImageStatus.LOCKED;
            case Error:
            case ErrorDeleting:
                return ImageStatus.ILLEGAL;
            default:
                return null;
        }
    }

    private OpenStackVolumeProviderProxy getVolumeProviderProxy(Guid storageDomainId) {
        if (proxy == null) {
            proxy = OpenStackVolumeProviderProxy.getFromStorageDomainId(storageDomainId);
        }
        return proxy;
    }

}

@@ -212,16 +212,65 @@
 Create;%0A
+import org.apache.commons.httpclient.HttpStatus;%0A
 import o
@@ -2234,32 +2234,880 @@
      %7D);%0A    %7D%0A%0A
+    public Void deleteDisk(final CinderDisk cinderDisk) %7B%0A        return execute(new Callable%3CVoid%3E() %7B%0A            @Override%0A            public Void call() %7B%0A                proxy.deleteVolume(cinderDisk.getId().toString());%0A                return null;%0A            %7D%0A        %7D);%0A    %7D%0A%0A    public boolean isDiskExist(final Guid id) %7B%0A        return execute(new Callable%3CBoolean%3E() %7B%0A            @Override%0A            public Boolean call() %7B%0A                try %7B%0A                    Volume volume = proxy.getVolumeById(id.toString());%0A                    return volume != null;%0A                %7D catch (OpenStackResponseException ex) %7B%0A                    if (ex.getStatus() == HttpStatus.SC_NOT_FOUND) %7B%0A                        return false;%0A                    %7D%0A                    throw ex;%0A                %7D%0A            %7D%0A        %7D);%0A    %7D%0A%0A
     public Image

add deleteDisk CinderBroker