package de.renew.net.inscription.transition;

import java.util.Collection;
import java.util.List;
import java.util.Vector;

import de.renew.engine.searcher.Occurrence;
import de.renew.engine.searcher.Searcher;
import de.renew.expression.Expression;
import de.renew.expression.VariableMapper;
import de.renew.net.NetInstance;
import de.renew.net.Transition;
import de.renew.net.inscription.TransitionInscription;

/**
 * An {@code ActionInscription} behaves like an {@link ExpressionInscription} but will be evaluated only during firing.
 * For example, if a transition is inscribed with "action y = f(x);", a corresponding {@code ActionInscription} will
 * be created. This {@code ActionInscription} will then cause the expression "y = f(x)" to be evaluated exactly once
 * during the firing of the transition, binding the variable y so that its value can be used on output arcs of the
 * transition.
 */
public class ActionInscription implements TransitionInscription {
    /**
     * The {@code Expression} that will be evaluated exactly once while the {@link #_transition} of this
     * {@code ActionInscription} fires.
     */
    private final Expression _expression;

    /**
     * The {@code Transition} that contains the {@code ActionInscription}.
     */
    private final Transition _transition;

    /**
     * Constructs a new {@code ActionInscription} based on the given expression and transition.
     *
     * @param expression the expression that will be evaluated exactly once when the transition fires
     * @param transition the transition that contains the {@code ActionInscription}
     */
    public ActionInscription(Expression expression, Transition transition) {
        _expression = expression;
        _transition = transition;
    }

    /**
     * Returns the {@code Expression} that this {@code ActionInscription} causes to be evaluated exactly once while its
     * transition fires.
     *
     * @return the {@code Expression}
     */
    public Expression getExpression() {
        return _expression;
    }

    @Override
    public Collection<Occurrence> makeOccurrences(
        VariableMapper mapper, NetInstance netInstance, Searcher searcher)
    {
        return new Vector<>(
            List.of(
                new ActionOccurrence(_expression, mapper, netInstance.getInstance(_transition))));
    }
}