package accrue.analysis.goals;

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

import polyglot.ast.NodeFactory;
import polyglot.frontend.ExtensionInfo;
import polyglot.frontend.Job;
import polyglot.frontend.Scheduler;
import polyglot.frontend.goals.Goal;
import polyglot.frontend.goals.VisitorGoal;
import polyglot.types.TypeSystem;
import accrue.AccrueScheduler;
import accrue.analysis.interprocanalysis.RegisterProceduresVisitor;
import accrue.analysis.interprocanalysis.Registrar;

public class RegisterProceduresGoal extends VisitorGoal {
    private static final Map<ExtensionInfo, Registrar> registrars =
            new LinkedHashMap<ExtensionInfo, Registrar>();

    public static Registrar registrar(ExtensionInfo extInfo) {
        Registrar r = registrars.get(extInfo);
        if (r == null) {
            r = new Registrar(extInfo);
            registrars.put(extInfo, r);
        }
        return r;
    }

    public static Goal create(Scheduler scheduler, Job job, TypeSystem ts,
            NodeFactory nf) {
        return scheduler.internGoal(new RegisterProceduresGoal(job, ts, nf));
    }

    protected RegisterProceduresGoal(Job job, TypeSystem ts, NodeFactory nf) {
        super(job,
              new RegisterProceduresVisitor(job,
                                            ts,
                                            nf,
                                            registrar(job.extensionInfo())));
    }

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

        return l;
    }
}
