package de.renew.shadowcompiler;

import java.util.Objects;

import de.renew.net.INetLookup;
import de.renew.net.Net;
import de.renew.net.loading.NetLoader;
import de.renew.simulator.api.ISimulationManager;
import de.renew.simulatorontology.loading.NetNotFoundException;
import de.renew.simulatorontology.shadow.ShadowNetLoader;
import de.renew.simulatorontology.shadow.ShadowNetSystem;

/**
 * A generic net loader implementation which delegates to a
 * {@link ShadowNetLoader}.
 * <p>
 * DefaultCompiledNetLoader.java <br>
 * Created: Tue Dec  5 2001 <br>
 * @author Michael Duvigneau
 **/
public class DefaultCompiledNetLoader implements NetLoader {
    private final ISimulationManager _simulationManager;
    private final INetLookup _netLookup;
    private final ShadowNetLoader _netLoader;

    /**
     * Creates a default compiled net loader for the given shadow
     * net system, delegating to the given shadow net loader.
     *
     * @param simulationManager the {@code ISimulationManager} to use for the compilation
     * @param netLookup the {@code INetLookup} to use for finding the compiled net
     * @param netLoader the net loader to delegate to
     * @throws NullPointerException if any of the parameters is {@code null}
     **/
    public DefaultCompiledNetLoader(
        ISimulationManager simulationManager, INetLookup netLookup, ShadowNetLoader netLoader)
    {
        _simulationManager =
            Objects.requireNonNull(simulationManager, "Missing ISimulationManager");
        _netLookup = Objects.requireNonNull(netLookup, "Missing INetLookup.");
        _netLoader = Objects.requireNonNull(netLoader, "Missing ShadowNetLoader.");
    }

    @Override
    public Net loadNet(String netName) throws NetNotFoundException {
        try {
            ShadowNetSystem netSystem = _netLoader.loadShadowNetSystem(netName);
            _simulationManager.addShadowNetSystem(netSystem);
            Net net = _netLookup.findForName(netName);
            if (net != null) {
                return net;
            }
        } catch (NetNotFoundException e) {
            // Just forward the information from the shadow net loader...
            throw e;
        } catch (Exception e) {
            throw new NetNotFoundException(netName, e);
        }
        throw new NetNotFoundException(netName);
    }
}