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

import be.iminds.ilabt.jfed.experiment.Experiment;
import be.iminds.ilabt.jfed.highlevel.jobs.report.JobReportWrappingLogger;
import be.iminds.ilabt.jfed.lowlevel.JFedException;
import be.iminds.ilabt.jfed.lowlevel.TestbedInfoSource;
import be.iminds.ilabt.jfed.lowlevel.api.AbstractGeniAggregateManager;
import be.iminds.ilabt.jfed.lowlevel.api.StitchingComputationService;
import be.iminds.ilabt.jfed.lowlevel.authority.AuthorityFinder;

import be.iminds.ilabt.jfed.fedmon.webapi.service.json.*;
import be.iminds.ilabt.jfed.lowlevel.stitching.StitchingDirector;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * User: twalcari
 * Date: 1/27/2016
 * Time: 11:24
 */
class StitchingAllocationDirector implements AllocationDirector {
    private final Experiment experiment;
    private final StitchingDirector director;

    StitchingAllocationDirector(Experiment experiment, TestbedInfoSource testbedInfoSource,
                                AuthorityFinder authorityFinder,
                                JobReportWrappingLogger stitchingDirectorLog) {
        this.experiment = experiment;
        this.director = new StitchingDirector(testbedInfoSource, authorityFinder,
                Date.from(experiment.getRequestedEndTime()), stitchingDirectorLog);
    }

    @Override
    public void reportGiveUp() {
        synchronized (director) {
            director.reportGiveup();
        }
    }

    @Override
    public boolean isGaveUp() {
        synchronized (director) {
            return director.isGaveUp();
        }
    }

    @Override
    public boolean areAnyActionsLeft() {
        synchronized (director) {
            return director.areAnyActionsLeft();
        }
    }

    @Override
    public List<StitchingDirector.StitchAction> getStitchActions() {
        synchronized (director) {
            return director.getStitchActions();
        }
    }

    @Override
    public StitchingDirector.AllocateVerdict processAllocateResult(StitchingDirector.StitchAction stitchAction, AbstractGeniAggregateManager.AggregateManagerReply reply) throws JFedException {
        synchronized (director) {
            return director.processAllocateResult(stitchAction, reply);
        }
    }

    @Override
    public void processListResourcesResult(Server auth, @Nullable String advertisementRspec) {
        synchronized (director) {
            director.processListResourcesResult(auth, advertisementRspec);
        }
    }

    @Override
    public void processDeleteResult(Server auth) throws JFedException {
        synchronized (director) {
            director.processDeleteResult(auth);
        }
    }

    @Override
    public StitchingDirector.AllocateVerdict reportReadyForRetry(Server auth) {
        synchronized (director) {
            return director.reportReadyForRetry(auth);
        }
    }

    public void setComputePathResult(StitchingComputationService.ComputePathResult computePathResult) throws JFedException {
        director.setComputePathResult(computePathResult);
    }

    public Collection<Server> getAllAuthorities() {
        return director.getAllAuthorities();
    }
}
