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.LocalVariable;
import de.renew.expression.VariableMapper;
import de.renew.net.Net;
import de.renew.net.NetInstance;
import de.renew.net.Transition;
import de.renew.net.inscription.TransitionInscription;

/**
 * A {@code CreationInscription} is used to indicate that an instance of a certain net should be created when firing
 * the corresponding transition. For example, a {@code CreationInscription} is created for a transition that is
 * inscribed with "x:new Net". In this case, "x" is the {@code LocalVariable} and {@code Net} the name of the net to
 * be created.
 */
public class CreationInscription implements TransitionInscription {
    /**
     * The {@code Net} that should be instantiated.
     */
    private final Net _net;

    /**
     * The {@code LocalVariable} that will be unified with the created instance of {@link #_net}.
     */
    private final LocalVariable _createVariable;

    /**
     * The Transition that contains the CreationInscription.
     */
    private final Transition _transition;

    /**
     * Constructs a new {@code CreationInscription} based on the given {@code Net} that should be instantiated,
     * the LocalVariable that will be unified with the created net instance
     * and the Transition that contains the inscription.
     *
     * @param net the Net that should be instantiated
     * @param createVariable the LocalVariable that will be unified with the created net instance
     * @param transition the Transition that contains the CreationInscription
     */
    public CreationInscription(Net net, LocalVariable createVariable, Transition transition) {
        _net = net;
        _createVariable = createVariable;
        _transition = transition;
    }

    /**
     * Returns the {@code LocalVariable} that will be unified with the net instance by this {@code CreationInscription}.
     *
     * @return the {@code LocalVariable} that will be unified with the created net instance
     */
    public LocalVariable getVariable() {
        return _createVariable;
    }

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