package de.renew.net.inscription.arc;

import de.renew.engine.common.SimulatorEventLogger;
import de.renew.engine.events.Putting;
import de.renew.engine.searcher.LateExecutable;
import de.renew.engine.searchqueue.SearchQueue;
import de.renew.net.SimulatablePlaceInstance;
import de.renew.simulatorontology.simulation.StepIdentifier;
import de.renew.unify.Variable;
import de.renew.util.Value;


class OutputArcExecutable implements LateExecutable {
    private final SimulatablePlaceInstance _placeInstance;
    private final Variable _tokenVar;
    private final Variable _timeVar;
    private final boolean _trace;

    OutputArcExecutable(
        SimulatablePlaceInstance placeInstance, Variable tokenVar, Variable timeVar, boolean trace)
    {
        _placeInstance = placeInstance;
        _tokenVar = tokenVar;
        _timeVar = timeVar;
        _trace = trace;
    }

    @Override
    public int phase() {
        return OUTPUT;
    }

    // We can put a token into an output place quickly.
    @Override
    public boolean isLong() {
        return false;
    }

    @Override
    public void execute(StepIdentifier stepIdentifier) {
        double time = SearchQueue.getTime();
        if (_timeVar != null) {
            time += ((Value) _timeVar.getValue()).doubleValue();
        }

        if (_trace) {
            // log activities on net level
            SimulatorEventLogger.log(
                stepIdentifier, new Putting(_tokenVar.getValue(), _placeInstance, time),
                _placeInstance);

        }
        _placeInstance.insertToken(_tokenVar.getValue(), time);
    }

    @Override
    public void executeAfterException(StepIdentifier stepIdentifier, Throwable t) {
        // Do not output any ordinary tokens.
        // The tokens might not even be available.
    }
}