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.controller.TaskExecution;
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.tasks.EditSSHKeysTask;
import be.iminds.ilabt.jfed.highlevel.tasks.HighLevelTaskFactory;
import be.iminds.ilabt.jfed.highlevel.util.AggregateManagerWrapperFactory;
import be.iminds.ilabt.jfed.lowlevel.JFedException;
import be.iminds.ilabt.jfed.lowlevel.api.user_spec.UserSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;

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

    private final Collection<UserSpec> userSpecs;
    private final HighLevelTaskFactory hltf;

    private final AggregateManagerWrapperFactory aggregateManagerWrapperFactory;
    private final JobStateFactory jobStateFactory;

    public EditSshKeysOnSfaExperimentPartJobSlice(Job<?> job, SfaExperimentPart experimentPart,
                                                  Collection<UserSpec> userSpecs, HighLevelTaskFactory hltf,
                                                  AggregateManagerWrapperFactory aggregateManagerWrapperFactory,
                                                  JobStateFactory jobStateFactory) {
        super(job, experimentPart);
        this.userSpecs = userSpecs;
        this.hltf = hltf;
        this.aggregateManagerWrapperFactory = aggregateManagerWrapperFactory;
        this.jobStateFactory = jobStateFactory;
    }

    @Override
    public ExperimentTaskStatus statefulRun() throws JFedException, InterruptedException {
        if (aggregateManagerWrapperFactory.getAggregateManagerWrapper(experimentPart.getConnectSfaAuthority())
                .isEditSshKeysSupported()) {

            final EditSshKeysOnExperimentPartState editSshKeysInExperimentPartState =
                    new EditSshKeysOnExperimentPartState(experimentPart, userSpecs);
            setAndRunState(editSshKeysInExperimentPartState);

            if (editSshKeysInExperimentPartState.getTaskExecution().getState() == TaskExecution.TaskState.SUCCESS) {
                setAndRunState(jobStateFactory.createGetStatusUntilReadyOrFailTaskState(job, experimentPart));
            } else {
                LOG.warn("Updating SSH-keys failed in {}", experimentPart.getName());
                return ExperimentTaskStatus.FAILED;
            }
        } else {
            LOG.info("Skipping updating SSH keys info on {}, as it is not supported", experimentPart.getConnectSfaAuthority().getName());
            return ExperimentTaskStatus.WARNING;
        }
        return ExperimentTaskStatus.SUCCESS;
    }

    public class EditSshKeysOnExperimentPartState extends SingleCallState<EditSSHKeysTask> {
        protected EditSshKeysOnExperimentPartState(SfaExperimentPart experimentPart, Collection<UserSpec> userSpecs) {
            super(String.format("Updating %d SSH keys on %s", userSpecs.size(), experimentPart.getName()),
                    hltf.getEditSshKeysTask(experiment.getSlice(), experimentPart.getConnectSfaAuthority(), userSpecs));
        }
    }
}
