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

import be.iminds.ilabt.jfed.experiment.SfaExperimentPart;
import be.iminds.ilabt.jfed.highlevel.jobs.ExperimentPartStateSlice;
import be.iminds.ilabt.jfed.highlevel.jobs.Job;
import be.iminds.ilabt.jfed.highlevel.jobs.parts.ExperimentPartController;
import be.iminds.ilabt.jfed.highlevel.jobs.states.JobStateFactory;
import be.iminds.ilabt.jfed.highlevel.tasks.HighLevelTaskFactory;
import be.iminds.ilabt.jfed.highlevel.util.AggregateManagerWrapperFactory;
import be.iminds.ilabt.jfed.lowlevel.api.user_spec.UserSpec;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.impl.AutomaticAggregateManagerWrapper;

import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import java.time.Instant;
import java.util.Collection;

/**
 * User: twalcari
 * Date: 1/12/2016
 * Time: 15:44
 */
@Singleton
public class SfaExperimentPartController implements ExperimentPartController<SfaExperimentPart> {
    private final Provider<HighLevelTaskFactory> hltfProvider;
    private final Provider<JobStateFactory> jobStateFactoryProvider;
    private final Provider<AggregateManagerWrapperFactory> aggregateManagerWrapperFactoryProvider;
    private final AutomaticAggregateManagerWrapper.AutomaticAggregateManagerWrapperFactory
            automaticAggregateManagerWrapperFactory;

    @Inject
    public SfaExperimentPartController(Provider<HighLevelTaskFactory> hltfProvider,
                                       Provider<JobStateFactory> jobStateFactoryProvider,
                                       Provider<AggregateManagerWrapperFactory> aggregateManagerWrapperFactoryProvider,
                                       AutomaticAggregateManagerWrapper.AutomaticAggregateManagerWrapperFactory automaticAggregateManagerWrapperFactory) {
        this.hltfProvider = hltfProvider;
        this.jobStateFactoryProvider = jobStateFactoryProvider;
        this.aggregateManagerWrapperFactoryProvider = aggregateManagerWrapperFactoryProvider;
        this.automaticAggregateManagerWrapperFactory = automaticAggregateManagerWrapperFactory;
    }

    @Override
    public boolean supportsRestore(SfaExperimentPart experimentPart) {
        return true;
    }

    @Override
    public ExperimentPartStateSlice<SfaExperimentPart> restore(Job<?> job, SfaExperimentPart experimentPart) {
        return new RestoreSfaExperimentPartStateSlice(job, experimentPart, hltfProvider.get(), jobStateFactoryProvider.get());
    }

    @Override
    public boolean supportsRenew(SfaExperimentPart experimentPart) {
        return true;
    }

    @Override
    public ExperimentPartStateSlice<SfaExperimentPart> renew(Job<?> job, SfaExperimentPart experimentPart, Instant newExpirationTime) {
        return new RenewSfaExperimentPartStateSlice(job, experimentPart, newExpirationTime, hltfProvider.get());
    }

    @Override
    public boolean supportsEditSshKeys(SfaExperimentPart experimentPart) {
        return !experimentPart.getConnectSfaAuthority().isEdgeVlan() &&
                automaticAggregateManagerWrapperFactory
                        .create(experimentPart.getConnectSfaAuthority())
                        .isEditSshKeysSupported();

    }

    @Override
    public ExperimentPartStateSlice<SfaExperimentPart> editSshKeys(Job<?> job, SfaExperimentPart experimentPart, Collection<UserSpec> userSpecs) {
        return new EditSshKeysOnSfaExperimentPartJobSlice(job, experimentPart, userSpecs, hltfProvider.get(),
                aggregateManagerWrapperFactoryProvider.get(), jobStateFactoryProvider.get());
    }

    @Override
    public UpdateSfaExperimentPartStateSlice update(Job<?> job, SfaExperimentPart experimentPart) {
        return new UpdateSfaExperimentPartStateSlice(job, experimentPart, hltfProvider.get());
    }

    @Override
    public ExperimentPartStateSlice<SfaExperimentPart> stop(Job<?> job, SfaExperimentPart experimentPart) {
        return new StopSfaExperimentPartStateSlice(job, experimentPart, hltfProvider.get(), jobStateFactoryProvider.get());
    }

}
