package de.renew.application;

import de.renew.engine.simulator.ISimulatorFactory;
import de.renew.engine.simulator.SimulatorFactory;
import de.renew.engine.thread.SimulationLockExecutorProvider;
import de.renew.net.INetLookup;
import de.renew.net.NetLookup;
import de.renew.simulator.api.IFinderRegistration;
import de.renew.simulator.api.ISimulationLockExecutor;
import de.renew.simulator.api.ISimulationManager;
import de.renew.simulator.api.ISimulatorExtensions;

/**
 * This class provides a single instance of an implementation of {@link ISimulationManager}.
 * To retrieve the global instance, use the method {@link #provider()}.
 */
public final class SimulationManagerProvider {
    private static final ISimulationManager SIMULATION_MANAGER;

    static {
        ISimulatorExtensions simulatorExtensions = SimulatorExtensionsProvider.provider();
        IFinderRegistration finderRegistration = FinderRegistrationProvider.provider();
        ISimulatorFactory simulatorFactory = new SimulatorFactory();
        INetLookup netLookup = new NetLookup();
        ISimulationLockExecutor lockExecutor = SimulationLockExecutorProvider.provider();
        SIMULATION_MANAGER = new SimulationManagerImpl(
            simulatorExtensions, finderRegistration, simulatorFactory, netLookup, lockExecutor);
    }

    /**
     * Private, as no instances of this class should exist.
     */
    private SimulationManagerProvider() {}

    /**
     * The provider method used by the {@link java.util.ServiceLoader}. Always returns the same instance.
     *
     * @return an instance of {@code ISimulationManager}
     */
    public static ISimulationManager provider() {
        return SIMULATION_MANAGER;
    }
}
