package be.iminds.ilabt.jfed.highlevel.tasks;

import be.iminds.ilabt.jfed.highlevel.controller.JFedHighLevelException;
import be.iminds.ilabt.jfed.highlevel.controller.Task;
import be.iminds.ilabt.jfed.highlevel.controller.TaskExecution;
import be.iminds.ilabt.jfed.highlevel.model.Slice;
import be.iminds.ilabt.jfed.highlevel.model.Sliver;
import be.iminds.ilabt.jfed.highlevel.util.AggregateManagerWrapperFactory;
import be.iminds.ilabt.jfed.lowlevel.JFedException;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.AggregateManagerWrapper;
import be.iminds.ilabt.jfed.util.GeniUrn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.List;

/**
 * User: twalcari
 * Date: 6/17/2015
 * Time: 16:18
 */
public class CreateImageTask extends Task {
    private static final Logger LOG = LoggerFactory.getLogger(CreateImageTask.class);

    //input parameters
    private final Slice slice;
    private final GeniUrn sliverUrn;
    private final String imageName;
    private final boolean global;
    private final boolean updatePrepare;

    //results
    private URL resultDiskImageUrl = null;
    private GeniUrn resultDiskImageUrn = null;

    //environment parameters
    private final AggregateManagerWrapperFactory aggregateManagerWrapperFactory;
    private final HighLevelTaskFactory highLevelTaskFactory;

    public CreateImageTask(Slice slice, GeniUrn sliverUrn, String imageName, boolean global, boolean updatePrepare,
                           AggregateManagerWrapperFactory aggregateManagerWrapperFactory, HighLevelTaskFactory highLevelTaskFactory) {
        super("Create Image on node " + sliverUrn);
        this.slice = slice;
        this.sliverUrn = sliverUrn;
        this.imageName = imageName;
        this.global = global;
        this.updatePrepare = updatePrepare;
        this.aggregateManagerWrapperFactory = aggregateManagerWrapperFactory;
        this.highLevelTaskFactory = highLevelTaskFactory;
    }

    @Override
    public void doTask(TaskExecution taskExecution) throws JFedException, InterruptedException {
        Sliver sliver = slice.findSliver(sliverUrn);
        assert (sliver != null);

        AggregateManagerWrapper amWrapper =
                aggregateManagerWrapperFactory.getAggregateManagerWrapper(taskExecution, sliver.getServer());
        if (!amWrapper.areUserDiskImageFunctionsSupported())
            throw new JFedHighLevelException("Authority " + sliver.getServer().getDefaultComponentManagerUrn() + " does not support create image.");
        AggregateManagerWrapper.ImageInfo imageInfo =
                amWrapper.createImage(slice.getUrn(), slice.getCredentials(), sliverUrn, imageName, global, updatePrepare);
        if (imageInfo != null) {
            try {
                resultDiskImageUrl = new URL(imageInfo.getUrl());
            } catch (MalformedURLException e) {
                LOG.warn("CreateImageTask createImage returned invalid URL: \"" + imageInfo.getUrl() + "\"", e);
                resultDiskImageUrl = null;
            }
            resultDiskImageUrn = GeniUrn.parse(imageInfo.getUrn());

        } else {
            throw new JFedHighLevelException("Did not receive a valid answer on CreateImage-call");
        }
    }

    @Override
    public List<Task> initDependsOn() {
        return Collections.singletonList(highLevelTaskFactory.getSliceCredential(slice));
    }

    public URL getResultDiskImageUrl() {
        return resultDiskImageUrl;
    }

    public GeniUrn getResultDiskImageUrn() {
        return resultDiskImageUrn;
    }
}
