package de.renew.api;

import java.io.IOException;
import java.io.ObjectInput;
import java.util.Properties;

import org.apache.log4j.Logger;

import de.renew.net.NetInstance;
import de.renew.plugin.ServiceLookupException;
import de.renew.plugin.ServiceLookupInfrastructure;
import de.renew.simulatorontology.simulation.SimulationRunningException;

/**
 * Static class of a {@code SimulationStateLoader}. Used to implement the
 * adapter pattern by delegating all calls to this class.
 */
public final class SimulationStateLoader {
    private static final ISimulationStateLoader SIMULATION_STATE_LOADER;
    private static final Logger LOGGER = Logger.getLogger(SimulationStateLoader.class);

    static {
        try {
            SIMULATION_STATE_LOADER = ServiceLookupInfrastructure.getInstance()
                .getFirstServiceProvider(ISimulationStateLoader.class);
        } catch (ServiceLookupException e) {
            LOGGER.error(
                "Could not find a service provider for " + ISimulationStateLoader.class + ": ", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * See {@link ISimulationStateLoader#loadState} for more information.
     *
     * @param input source stream (see note about {@code RenewObjectInputStream}
     *              in the linked documentation).
     * @param properties additional properties that specify this simulation
     *        environment. These properties will override any default values
     *        from the plugin properties. May be {@code null}.
     * @return array of explicitly stored net instances (e.g. to be displayed to
     *         the user).
     * @throws IOException if an error occurs during reading the input stream
     * @throws ClassNotFoundException if an unknown object type was included in the state
     * @throws SimulationRunningException if a simulation is already running.
     */
    public static NetInstance[] loadState(ObjectInput input, Properties properties)
        throws IOException, ClassNotFoundException
    {
        return SIMULATION_STATE_LOADER.loadState(input, properties);
    }
}