package org.ovirt.engine.api.restapi.resource;

import java.util.List;

import javax.ws.rs.core.Response;

import org.ovirt.engine.api.model.Template;
import org.ovirt.engine.api.model.VmPool;
import org.ovirt.engine.api.model.VmPools;
import org.ovirt.engine.api.resource.VmPoolResource;
import org.ovirt.engine.api.resource.VmPoolsResource;
import org.ovirt.engine.core.common.action.AddVmPoolWithVmsParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VmPoolParametersBase;
import org.ovirt.engine.core.common.businessentities.VDSGroup;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VmPoolType;
import org.ovirt.engine.core.common.businessentities.VmTemplate;
import org.ovirt.engine.core.common.interfaces.SearchType;
import org.ovirt.engine.core.common.queries.GetVmTemplateParameters;
import org.ovirt.engine.core.common.queries.IdQueryParameters;
import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
import org.ovirt.engine.core.common.queries.VdcQueryType;
import org.ovirt.engine.core.compat.Guid;

public class BackendVmPoolsResource
        extends AbstractBackendCollectionResource<VmPool, org.ovirt.engine.core.common.businessentities.VmPool>
    implements VmPoolsResource {

    static final String SUB_COLLECTION = "permissions";

    public BackendVmPoolsResource() {
        super(VmPool.class, org.ovirt.engine.core.common.businessentities.VmPool.class);
    }

    @Override
    public VmPools list() {
        if (isFiltered()) {
            return mapCollection(getBackendCollection(VdcQueryType.GetAllVmPoolsAttachedToUser,
                    new VdcQueryParametersBase()));
        } else {
            return mapCollection(getBackendCollection(SearchType.VmPools));
        }
    }

    @Override
    public Response add(VmPool pool) {
        validateParameters(pool, "name", "template.id|name", "cluster.id|name");

        VmTemplate template = getVmTemplate(pool);
        if (namedTemplate(pool)) {
            pool.getTemplate().setId(template.getId().toString());
        }

        if (namedCluster(pool)) {
            pool.getCluster().setId(getClusterId(pool));
        }

        org.ovirt.engine.core.common.businessentities.VmPool entity = map(pool);
        entity.setVmPoolType(VmPoolType.Automatic);

        VM vm = mapToVM(pool, template);

        int size = pool.isSetSize() ? pool.getSize() : 1;

        return performCreate(VdcActionType.AddVmPoolWithVms,
                               new AddVmPoolWithVmsParameters(entity, vm, size, -1),
                               new QueryIdResolver<Guid>(VdcQueryType.GetVmPoolById,
                                                   IdQueryParameters.class));
    }

    @Override
    public Response performRemove(String id) {
        return performAction(VdcActionType.RemoveVmPool, new VmPoolParametersBase(asGuid(id)));
    }

    @Override
    @SingleEntityResource
    public VmPoolResource getVmPoolSubResource(String id) {
        return inject(new BackendVmPoolResource(id, this));
    }

    @Override
    public VmPool doPopulate(VmPool pool, org.ovirt.engine.core.common.businessentities.VmPool entity) {
        return pool;
    }

    @Override
    protected VmPool deprecatedPopulate(VmPool model, org.ovirt.engine.core.common.businessentities.VmPool entity) {
        if (model.isSetSize() && model.getSize() > 0) {
            VM vm = getVM(model);
            model.setTemplate(new Template());
            model.getTemplate().setId(vm.getVmtGuid().toString());
        }
        return model;
    }

    private VM getVM(VmPool model) {
        if (isFiltered()) {
            return getEntity(VM.class,
                         VdcQueryType.GetVmDataByPoolId,
                         new IdQueryParameters(asGuid(model.getId())),
                         model.getId());
        }
        return getEntity(VM.class, SearchType.VM, "Vms: pool=" + model.getName());
    }

    protected VM mapToVM(VmPool model, VmTemplate template) {
        // REVISIT: we should reverse the mapping order here,
        // so that we map from template->VM in the first instance
        // and then override any values (memory size, boot order etc.)
        // that are set in the client-provided VmPool instance
        VM vm = getMapper(VmPool.class, VM.class).map(model, null);
        vm.getStaticData().setMemSizeMb(template.getMemSizeMb());
        return vm;
    }

    protected VmPools mapCollection(List<org.ovirt.engine.core.common.businessentities.VmPool> entities) {
        VmPools collection = new VmPools();
        for (org.ovirt.engine.core.common.businessentities.VmPool entity : entities) {
            collection.getVmPools().add(addLinks(populate(map(entity), entity)));
        }
        return collection;
    }

    protected boolean namedCluster(VmPool pool) {
        return pool.getCluster().isSetName() && !pool.getCluster().isSetId();
    }

    protected String getClusterId(VmPool pool) {
        return getEntity(VDSGroup.class,
                         SearchType.Cluster,
                         "Cluster: name=" + pool.getCluster().getName()).getId().toString();
    }

    protected boolean namedTemplate(VmPool pool) {
        return pool.getTemplate().isSetName() && !pool.getTemplate().isSetId();
    }

    protected VmTemplate getVmTemplate(VmPool pool) {
        if (pool.getTemplate().isSetId()) {
            return getEntity(VmTemplate.class,
                             VdcQueryType.GetVmTemplate,
                             new GetVmTemplateParameters(asGuid(pool.getTemplate().getId())),
                             pool.getTemplate().getId());
        } else {
            return getEntity(VmTemplate.class,
                             SearchType.VmTemplate,
                             "Template: name=" + pool.getTemplate().getName());
        }
    }
}

@@ -705,24 +705,218 @@
 ities.Vm
-PoolType
+Dynamic;%0Aimport org.ovirt.engine.core.common.businessentities.VmPoolType;%0Aimport org.ovirt.engine.core.common.businessentities.VmStatic;%0Aimport org.ovirt.engine.core.common.businessentities.VmStatistics
 ;%0Aimport
@@ -4289,226 +4289,140 @@
  // 
-REVISIT: we should reverse the mapping order here,%0A        // so that we map from template-%3EVM in the first instance%0A        // and then override any values (memory size, boot order etc.)%0A        // that are set in 
+apply template%0A        VmStatic vmStatic = getMapper(VmTemplate.class, VmStatic.class).map(template, null);%0A        // override wi
 th
-e
  cli
@@ -4438,23 +4438,12 @@
 ded 
-VmPool instance
+data
 %0A   
@@ -4505,80 +4505,64 @@
 l, n
-ull);%0A        vm.getStaticData().setMemSizeMb(template.getMemSizeMb(
+ew VM(vmStatic, new VmDynamic(), new VmStatistics()
 ));%0A
+%0A
     

Apply template on VmPool creation using REST API