package de.renew.net.inscription.transition;

import java.io.ObjectStreamException;
import java.io.Serial;
import java.util.Collection;
import java.util.Collections;

import de.renew.engine.searcher.Occurrence;
import de.renew.engine.searcher.Searcher;
import de.renew.engine.thread.SimulationThreadPool;
import de.renew.expression.VariableMapper;
import de.renew.net.NetInstance;
import de.renew.net.inscription.TransitionInscription;
import de.renew.unify.Impossible;


/**
 * The {@code ManualInscription} tags a transition as non-spontaneous.
 * The class uses the singleton design pattern.
 * <p>
 * The {@code ManualInscription} has no occurrences because it has no
 * effect when a transition fires.
 * The only effect of this inscription is that the transition property
 * {@link de.renew.net.Transition#isSpontaneous} is {@code false}
 * whenever the {@code ManualInscription} singleton is detected among
 * the transition's inscriptions
 * </p>
 *
 * @author Olaf Kummer
 * @author Michael Duvigneau
 **/
public class ManualInscription implements TransitionInscription {

    /**
     * Stores the singleton instance of this class.
     **/
    private static ManualInscription _singleton;

    /**
     * This class cannot be instantiated except for the singleton
     * instance which can be obtained by a call to {@link #getInstance}.
     **/
    private ManualInscription() {}

    /**
     * Obtains a reference to the singleton instance of this class.
     * The instance is created by the first call of this method.
     *
     * @return  the one and only {@code ManualInscription} instance
     **/
    public static synchronized ManualInscription getInstance() {
        assert SimulationThreadPool.isSimulationThread() : "is not in a simulation thread";
        if (_singleton == null) {
            _singleton = new ManualInscription();
        }

        return _singleton;
    }

    /**
     * The {@code ManualInscription} has no effect when a transition
     * fires, therefore the returned set of occurrences is empty.
     *
     * @param mapper          {@inheritDoc}
     * @param netInstance     {@inheritDoc}
     * @param searcher        {@inheritDoc}
     * @return                an empty set
     * @exception Impossible  never.
     **/
    @Override
    public Collection<Occurrence> makeOccurrences(
        VariableMapper mapper, NetInstance netInstance, Searcher searcher) throws Impossible
    {
        assert SimulationThreadPool.isSimulationThread() : "is not in a simulation thread";
        return Collections.emptySet();
    }

    /**
     * This method is called automatically by the Java deserialization
     * mechanism, and it ensures the singleton property of this class.
     *
     * @return  the singleton instance of {@code ManualInscription}
     * @exception ObjectStreamException  if an error occurs
     **/
    @Serial
    private Object readResolve() throws ObjectStreamException {
        return getInstance();
    }
}