package de.renew.engine.searcher;

import de.renew.simulatorontology.simulation.StepIdentifier;


/**
 * This interface describes executable objects that
 * produce irrecoverable side effects.
 * Processing proceeds in certain phases.
 * <p>
 * Here we list all phases that may occur.
 * First of all, the irrevocable start of the
 * transition's firing is announced.
 * Then trace messages are printed. The definite and
 * irrevocable creation of net instances should be
 * confirmed next, so that the net instances can
 * participate in actions later on. Output arcs come
 * next, before the transition's termination is announced.
 * In the case of synchronisation requests there are
 * no output arcs, but the end of the synchronisation needs
 * to be declared.
 */
public interface LateExecutable extends Executable {
    /**
     * The Phase in which the irrevocable start of an action is announced.
     */
    int START = -9999;

    /**
     * Phase in which trace messages are printed.
     */
    int TRACE = 0;

    /**
     * Phase in which the creation of net instances is confirmed.
     * This phase should be used for actions that create net
     * instances, so that the net instances can participate
     * in actions later on.
     */
    int LATE_CONFIRM = 1;

    /**
     * Phase in which output arcs are processed.
     */
    int ACTION = 2;

    /**
     * Phase in which output is produced.
     */
    int OUTPUT = 3;

    /**
     * Phase in which the irrevocable completion of an action is announced.
     */
    int COMPLETION_NOTIFY = OUTPUT;

    /**
     * The Phase in which the irrevocable end of an action is announced.
     */
    int END = 9999;

    /**
     * Get the phase during which this executable should execute.
     * <p>
     * The late executables will be executed after all
     * early executables regardless of the phase. The phase
     * is local to late executables.
     */
    @Override
    int phase();

    /**
     * Returns true, if this executable might take a long time to
     * execute.
     *
     * @return {@code true}, if this executable might take a long time to execute
     */
    boolean isLong();

    /**
     * Execute this executable if an exception occurred
     * in a previous late executable.
     *
     * @param stepIdentifier the action to execute, if the exception occurred
     * @param t the {@link Throwable} exception, which occurred in a previous late executable
     */
    void executeAfterException(StepIdentifier stepIdentifier, Throwable t);
}