package accrue.analysis.goals;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import polyglot.frontend.CyclicDependencyException;
import polyglot.frontend.ExtensionInfo;
import polyglot.frontend.Job;
import polyglot.frontend.Scheduler;
import polyglot.frontend.goals.Barrier;
import polyglot.frontend.goals.Goal;
import polyglot.frontend.goals.VisitorGoal;
import polyglot.util.InternalCompilerError;
import polyglot.visit.LocalClassRemover;
import accrue.AccrueScheduler;

public class MoveLocalClassesGoal extends Barrier {
    public static MoveLocalClassesGoal singleton(ExtensionInfo extInfo) {
        Scheduler scheduler = extInfo.scheduler();
        return (MoveLocalClassesGoal) scheduler.internGoal(new MoveLocalClassesGoal(scheduler));
    }

    protected MoveLocalClassesGoal(Scheduler scheduler) {
        super(scheduler);
    }

    @Override
    public Collection<Goal> prerequisiteGoals(Scheduler scheduler) {
        List<Goal> l = new ArrayList<Goal>();
        l.add(((AccrueScheduler) scheduler).helper().PreModificationBarrier());

        l.addAll(super.prerequisiteGoals(scheduler));
        return l;
    }

    @Override
    public Goal goalForJob(Job job) {
        Goal g =
                scheduler.internGoal(new VisitorGoal(job,
                                                     new LocalClassRemover(job,
                                                                           job.extensionInfo()
                                                                              .typeSystem(),
                                                                           job.extensionInfo()
                                                                              .nodeFactory())));
        AccrueScheduler sched = (AccrueScheduler) scheduler;
        try {
            g.addPrerequisiteGoal(sched.helper().PreModificationBarrier(),
                                  scheduler);
        }
        catch (CyclicDependencyException e) {
            throw new InternalCompilerError(e);
        }
        return g;
    }
}
