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

import be.iminds.ilabt.jfed.highlevel.controller.Task;
import be.iminds.ilabt.jfed.highlevel.controller.TaskExecution;
import be.iminds.ilabt.jfed.highlevel.controller.TaskThread;
import be.iminds.ilabt.jfed.highlevel.model.SfaModel;
import be.iminds.ilabt.jfed.highlevel.model.Slice;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.lowlevel.JFedException;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.UserAndSliceApiWrapper;
import be.iminds.ilabt.jfed.util.GeniUrn;
import be.iminds.ilabt.jfed.util.JavaFXLogger;
import javafx.application.Platform;

import java.util.Collections;
import java.util.List;

/**
 * User: twalcari
 * Date: 6/17/2015
 * Time: 11:04
 */
public class ResolveUserAndSlicesTask extends Task {


    private final UserAndSliceApiWrapper userAndSliceApiWrapper;
    private final JavaFXLogger logger;
    private final GeniUserProvider geniUserProvider;
    private final SfaModel sfaModel;
    private final TaskThread tt;
    private final HighLevelTaskFactory highLevelTaskFactory;

    public ResolveUserAndSlicesTask(UserAndSliceApiWrapper userAndSliceApiWrapper, JavaFXLogger logger,
                                    GeniUserProvider geniUserProvider, SfaModel sfaModel,
                                    TaskThread tt, HighLevelTaskFactory highLevelTaskFactory) {
        super("Resolve User & Slices");
        this.userAndSliceApiWrapper = userAndSliceApiWrapper;
        this.logger = logger;
        this.geniUserProvider = geniUserProvider;
        this.sfaModel = sfaModel;
        this.tt = tt;
        this.highLevelTaskFactory = highLevelTaskFactory;
    }

    @Override
    public void doTask(TaskExecution taskExecution) throws JFedException, InterruptedException {

        List<GeniUrn> sliceUrns =
                userAndSliceApiWrapper.getSlicesForUser(
                        JavaFXLogger.wrap(logger, taskExecution),
                        geniUserProvider.getLoggedInGeniUser().getUserUrn());

        //note: resolveUser call result might not have triggered listener yet, so sfaModel might not yet know of it!

        for (final GeniUrn sliceUrn : sliceUrns) {
            //TODO very dirty, fix! (see TODOs below for info)
            //TODO how to wait for result to be processed so we can request slice resolve? One way is to run this in JavaFX thread,
            //TODO     it is a dirty method, as it relies on much implementation info.
            //TODO     a better method would be to have a method that waits for all pending updates in SfaModel or the SfaModelListeners.
            Platform.runLater(() -> {
                Slice slice = sfaModel.getSlice(sliceUrn);
                assert slice != null;

                //TODO reblock self and add these as dependencies instead
                //Note: this to do requires that the other is done first
                tt.addTask(highLevelTaskFactory.getAggregatesForSlice(slice));
            });
        }
    }

    @Override
    public List<Task> initDependsOn() {
        return Collections.singletonList(highLevelTaskFactory.getUserCredential());
    }
}
