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

import be.iminds.ilabt.jfed.highlevel.controller.Task;
import be.iminds.ilabt.jfed.highlevel.model.Sliver;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.*;
import be.iminds.ilabt.jfed.rspec.model.ModelRspec;
import be.iminds.ilabt.jfed.rspec.rspec_source.RequestRspecSource;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.time.Instant;
import java.util.Collection;
import java.util.Date;

/**
 * Parent class for tasks who create slivers (reserved or non reserved)
 * User: twalcari
 * Date: 6/17/2015
 * Time: 17:02
 */
public abstract class CreateTask extends Task {
    protected boolean failedDueToNotEnoughFreeResources = false;

    public CreateTask(String name) {
        super(name);
    }

    public abstract Server getServer();

    public final boolean hasFailedDueToNotEnoughFreeResources() {
        return failedDueToNotEnoughFreeResources;
    }


    /**
     * see FEDIBBTDEV-1334: ION and others see "expires" in the request RSpec as the requested sliver expiration
     * so if not yet specified, we add it here
     * <p>
     * note: this modifies the ModelRspec in the original RequestRspecSource, AND returns a new one (to reset derived rspec forms such as xml string)
     */
    protected RequestRspecSource updateExpires(@Nonnull Server server, @Nonnull RequestRspecSource origSource,
                                               @Nullable Instant requestedEndTime) {
        if (requestedEndTime != null && server.hasFlag(Server.Flag.workaroundAddExpiresAttributeToRequestRspec)) {
            ModelRspec modelRspec = origSource.getModelRspec();
            //always overwrite see FEDIBBTDEV-1410
            //don't ever modify the original! The user doesn't expect expires to be added (or deleted)! see FEDIBBTDEV-1448
            modelRspec = modelRspec.copy();
            modelRspec.setExpires(Date.from(requestedEndTime));
            return new RequestRspecSource(modelRspec);
        } else {
            //remove expires
            ModelRspec modelRspec = origSource.getModelRspec();
            modelRspec = modelRspec.copy();
            modelRspec.setExpires((String) null);
            return new RequestRspecSource(modelRspec);
        }
    }

    public abstract Collection<Sliver> getCreatedSlivers();
}