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

import be.iminds.ilabt.jfed.experiment.Experiment;
import be.iminds.ilabt.jfed.experiment.ExperimentPart;
import be.iminds.ilabt.jfed.experiment.SfaExperimentPart;
import be.iminds.ilabt.jfed.experiment.tasks.ExperimentTaskStatus;
import be.iminds.ilabt.jfed.highlevel.controller.TaskThread;
import be.iminds.ilabt.jfed.highlevel.jobs.states.JobStateFactory;
import be.iminds.ilabt.jfed.highlevel.model.Sliver;
import be.iminds.ilabt.jfed.highlevel.tasks.HighLevelTaskFactory;
import be.iminds.ilabt.jfed.highlevel.tasks.RestartTask;

/**
 * User: twalcari
 * Date: 12/1/2015
 * Time: 17:28
 */
public class RebootJob extends AbstractJob<Void> {

    private final JobStateFactory jobStateFactory;

    private final ExperimentPart experimentPart;
    private final RestartTask restartTask;


    public RebootJob(Experiment experiment, Sliver sliver, HighLevelTaskFactory hltf, TaskThread tt, JobStateFactory jobStateFactory) {
        super("Reboot sliver " + sliver.getUrn().toString(), experiment, hltf, tt);
        this.experimentPart = experiment.getPart(sliver);
        this.jobStateFactory = jobStateFactory;

        this.restartTask = hltf.restartSliver(sliver);
    }


    public RebootJob(ExperimentPart experimentPart, HighLevelTaskFactory hltf, TaskThread tt, JobStateFactory jobStateFactory) {
        super("Rebooting nodes on " + experimentPart.getName(), experimentPart.getExperiment(), hltf, tt);
        this.experimentPart = experimentPart;
        this.jobStateFactory = jobStateFactory;

        if(!(experimentPart instanceof SfaExperimentPart))
            throw new UnsupportedOperationException("Can only reload OS on SfaExperimentPart!");

        this.restartTask = hltf.restartSlice(experiment.getSlice(), ((SfaExperimentPart)experimentPart).getConnectSfaAuthority());
    }


    @Override
    public Void execute() throws Exception {
        RestartState restartState = new RestartState();
        setAndRunState(restartState);

        if(restartState.getStatus() == ExperimentTaskStatus.SUCCESS){
            if(!(experimentPart instanceof SfaExperimentPart))
                throw new UnsupportedOperationException("Can only reload OS on SfaExperimentPart!");

            setAndRunState(jobStateFactory.createGetStatusUntilReadyOrFailTaskState(this, (SfaExperimentPart)experimentPart));
        }
        return null;
    }

    public class RestartState extends SingleCallState<RestartTask> {
        protected RestartState() {
            super(RebootJob.this.getName(), RebootJob.this.restartTask);
        }
    }

}
