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

import be.iminds.ilabt.jfed.experiment.SfaExperimentPart;
import be.iminds.ilabt.jfed.experiment.tasks.ExperimentTaskStatus;
import be.iminds.ilabt.jfed.highlevel.jobs.ExperimentPartStateSlice;
import be.iminds.ilabt.jfed.highlevel.jobs.Job;
import be.iminds.ilabt.jfed.highlevel.jobs.SingleCallState;
import be.iminds.ilabt.jfed.highlevel.jobs.states.JobStateFactory;
import be.iminds.ilabt.jfed.highlevel.jobs.states.StopExperimentAtAuthorityPartState;
import be.iminds.ilabt.jfed.highlevel.model.InternalState;
import be.iminds.ilabt.jfed.highlevel.tasks.HighLevelTaskFactory;
import be.iminds.ilabt.jfed.highlevel.tasks.RegisterStopToSLACollectorTask;
import be.iminds.ilabt.jfed.lowlevel.JFedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * User: twalcari
 * Date: 1/13/2016
 * Time: 13:45
 */
public class StopSfaExperimentPartStateSlice extends ExperimentPartStateSlice<SfaExperimentPart> {
    private static final Logger LOG = LoggerFactory.getLogger(StopSfaExperimentPartStateSlice.class);

    private final HighLevelTaskFactory hltf;
    private final JobStateFactory jobStateFactory;

    public StopSfaExperimentPartStateSlice(Job<?> job, SfaExperimentPart experimentPart, HighLevelTaskFactory hltf, JobStateFactory jobStateFactory) {
        super(job, experimentPart);
        this.hltf = hltf;
        this.jobStateFactory = jobStateFactory;
    }

    @Override
    public ExperimentTaskStatus statefulRun() throws JFedException, InterruptedException {
        experimentPart.setState(InternalState.DELETING);

        final StopExperimentAtAuthorityPartState stopPartState =
                jobStateFactory.createStopExperimentAtAuthorityPartState(job, experimentPart);
        setAndRunState(stopPartState);

        if (experiment.isRequestSla()) {
            if (experiment.getSlice().getUuid() != null) {
                setAndRunState(new RegisterStopToSlaCollectorState(experimentPart));
            } else {
                LOG.warn("Could not register stop of experiment {} at authority {} to SLA Collector because no UUID is available",
                        experiment.getName(), experimentPart.getName());
            }

        }

        if (stopPartState.getStatus() == ExperimentTaskStatus.SUCCESS)
            experimentPart.setState(InternalState.DELETED);
        else
            experimentPart.setState(InternalState.FAILED);

        return stopPartState.getStatus();
    }

    private class RegisterStopToSlaCollectorState extends SingleCallState<RegisterStopToSLACollectorTask> {

        protected RegisterStopToSlaCollectorState(SfaExperimentPart experimentPart) {
            super("Registering termination of resources to SLA Collector",
                    hltf.registerStopToSLACollector(experiment.getSlice(), experimentPart.getConnectSfaAuthority()));
        }
    }
}
