package de.renew.net.inscription.transition;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

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.net.Net;
import de.renew.net.NetInstance;
import de.renew.net.TransitionInstance;
import de.renew.net.inscription.AbstractOccurrence;
import de.renew.unify.Impossible;
import de.renew.unify.Unify;
import de.renew.unify.Variable;

/**
 * A {@code CreationOccurrence} represents the occurrence of an {@link CreationInscription} in a net instance.
 * It is responsible for creating a new net instance when executed.
 */
class CreationOccurrence extends AbstractOccurrence {
    /** The {@code Variable} that should contain the reference to the created net. */
    private final Variable _variable;
    /** The {@code Net} that is being instantiated. */
    private final Net _net;
    /** The {@code NetInstance} of {@link #_net} that will be created when the {@code CreationOccurrence} occurs. */
    private NetInstance _newNetInstance;

    /**
     * Creates a new {@code CreationOccurrence} using the given values.
     * 
     * @param variable the variable that will be unified with the created net instance
     * @param net the net that will be instantiated
     * @param transitionInstance the transition instance that the {@code CreationOccurrence} is related to
     */
    public CreationOccurrence(Variable variable, Net net, TransitionInstance transitionInstance) {
        super(transitionInstance);
        _variable = variable;
        _net = net;
    }

    @Override
    public Collection<Binder> makeBinders(Searcher searcher) throws Impossible {
        // Create the new net instance.
        _newNetInstance = _net.getInstantiator().makeInstance();


        // Assign it to the variable.
        Unify.unify(_variable, _newNetInstance, searcher.getStateRecorder());

        // Nothing more to be done.
        return Collections.emptySet();
    }

    @Override
    public Collection<Executable> makeExecutables(VariableMapperCopier copier) {
        return Arrays
            .asList(new EarlyConfirmer(_newNetInstance), new LateConfirmer(_newNetInstance));
    }

    @Override
    public OccurrenceDescription makeOccurrenceDescription(
        VariableMapperCopier variableMapperCopier)
    {
        return null;
    }
}