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.model.Slice;
import be.iminds.ilabt.jfed.log.ResultListener;
import be.iminds.ilabt.jfed.lowlevel.JFedException;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.UserAndSliceApiWrapper;
import be.iminds.ilabt.jfed.fedmon.webapi.service.json.*;
import be.iminds.ilabt.jfed.util.GeniUrn;
import be.iminds.ilabt.jfed.util.JavaFXLogger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.time.Instant;
import java.util.*;

/**
 * User: twalcari
 * Date: 6/17/2015
 * Time: 15:21
 */
public final class RegisterSliversTask extends Task {
    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(RegisterSliversTask.class);

    @Nonnull
    private final Slice slice;
    @Nonnull
    private final Collection<GeniUrn> createdSliverUrns;
    @Nullable
    private final Task extraTaskToDependOn;
    @Nullable
    private final Instant sliverExpirationDate;
    @Nonnull
    private final Server auth;
    @Nonnull
    private final ResultListener[] extraResultListeners;

    private final UserAndSliceApiWrapper userAndSliceApiWrapper;
    private final JavaFXLogger logger;
    private final HighLevelTaskFactory highLevelTaskFactory;

    public RegisterSliversTask(@Nonnull Slice slice, @Nonnull Server auth,
                               @Nonnull Collection<GeniUrn> createdSliverUrns, @Nullable Instant sliverExpirationDate,
                               @Nullable Task extraTaskToDependOn,
                               UserAndSliceApiWrapper userAndSliceApiWrapper, JavaFXLogger logger,
                               HighLevelTaskFactory highLevelTaskFactory,
                               @Nonnull ResultListener... extraResultListeners) {
        super("Registering slivers created @ " + auth.getDefaultComponentManagerUrn());

        this.slice = slice;
        this.createdSliverUrns = createdSliverUrns;
        this.sliverExpirationDate = sliverExpirationDate;
        this.auth = auth;
        this.extraTaskToDependOn = extraTaskToDependOn;

        this.userAndSliceApiWrapper = userAndSliceApiWrapper;
        this.logger = logger;
        this.highLevelTaskFactory = highLevelTaskFactory;
        this.extraResultListeners = extraResultListeners;
    }

    @Override
    protected void doTask(TaskExecution taskExecution) throws JFedException, InterruptedException {
        ResultListener[] resultListeners = Arrays.copyOf(extraResultListeners, extraResultListeners.length + 1);
        resultListeners[extraResultListeners.length] = taskExecution;
        JavaFXLogger logger = JavaFXLogger.wrap(this.logger, resultListeners);

        Collection<GeniUrn> sliverUrns = createdSliverUrns;

        LOG.debug("RegisterSliversTask has " + sliverUrns.size() + " sliver Urns to register.");
        if (!sliverUrns.isEmpty())
            userAndSliceApiWrapper.registerAggregatesForSlice(logger,
                    slice.getCredentials(), slice.getUrn(),
                    auth.getDefaultComponentManagerAsGeniUrn(), sliverUrns,
                    sliverExpirationDate != null ? Date.from(sliverExpirationDate) : null);
    }

    @Override
    public List<Task> initDependsOn() {
        List<Task> res = new ArrayList<>();
        if (extraTaskToDependOn != null)
            res.add(extraTaskToDependOn);
        res.add(highLevelTaskFactory.getSliceCredential(slice));
        return res;
    }
}
