package de.renew.net.inscription.transition;

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

import de.renew.engine.searcher.Binder;
import de.renew.engine.searcher.Executable;
import de.renew.engine.searcher.OccurrenceDescription;
import de.renew.engine.searcher.Searcher;
import de.renew.engine.searcher.VariableMapperCopier;
import de.renew.engine.thread.SimulationThreadPool;
import de.renew.expression.Expression;
import de.renew.expression.VariableMapper;
import de.renew.net.TransitionInstance;
import de.renew.net.inscription.AbstractOccurrence;
import de.renew.unify.IStateRecorder;
import de.renew.unify.Impossible;
import de.renew.unify.Variable;


abstract class EnumeratorOccurrence extends AbstractOccurrence {
    private final Expression _expression;
    private final VariableMapper _mapper;
    private final boolean _checkBound;

    public EnumeratorOccurrence(
        Expression expression, boolean checkBound, VariableMapper mapper,
        TransitionInstance tInstance)
    {
        super(tInstance);
        assert SimulationThreadPool.isSimulationThread() : "is not in a simulation thread";
        _expression = expression;
        _checkBound = checkBound;
        _mapper = mapper;
    }

    public abstract Collection<?> getCandidates(Object pattern);

    @Override
    public Collection<Binder> makeBinders(Searcher searcher) throws Impossible {
        assert SimulationThreadPool.isSimulationThread() : "is not in a simulation thread";
        IStateRecorder stateRecorder = searcher.getStateRecorder();
        Variable var = new Variable(
            _expression.startEvaluation(_mapper, stateRecorder, searcher.getCalculationChecker()),
            stateRecorder);
        List<Binder> binders = new ArrayList<>();
        binders.add(new EnumeratorBinder(this, _checkBound, var));
        return binders;
    }

    @Override
    public Collection<Executable> makeExecutables(VariableMapperCopier copier) {
        assert SimulationThreadPool.isSimulationThread() : "is not in a simulation thread";
        return Collections.emptySet();
    }

    @Override
    public OccurrenceDescription makeOccurrenceDescription(
        VariableMapperCopier variableMapperCopier)
    {
        assert SimulationThreadPool.isSimulationThread() : "is not in a simulation thread";
        return null;
    }
}