package de.renew.remote;

import java.rmi.RemoteException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import de.renew.engine.thread.SimulationThreadPool;
import de.renew.net.NetElementID;
import de.renew.net.Place;
import de.renew.simulatorontology.simulation.SimulationEnvironment;


/**
 * This class implements the <code>PlaceAccessor</code> interface
 * and nothing more.
 * PlaceAccessorImpl.java
 * Created: Fri Jul 14  2000
 * @author Michael Duvigneau
 */
public class PlaceAccessorImpl extends ObjectAccessorImpl implements PlaceAccessor {
    /**
     * The LOGGER variable is a static final instance of the Log4j Logger
     * specifically associated with the PlaceAccessorImpl class.
     * This logger is used to log messages such as errors or debug information
     * to track execution and identify issues during the runtime of this class.
     */
    public static final org.apache.log4j.Logger LOGGER =
        org.apache.log4j.Logger.getLogger(PlaceAccessorImpl.class);

    /**
     * Creates a new place accessor for the given place.
     *
     * @param place the place to access
     * @param env the simulation environment that contains the place
     * @exception java.rmi.RemoteException if an RMI failure occured.
     */
    public PlaceAccessorImpl(Place place, SimulationEnvironment env) throws RemoteException {
        super(place, env);
    }

    /* This method is specified by the PlaceAccessor interface. */
    @Override
    public NetElementID getID() throws RemoteException {
        Future<NetElementID> future =
            SimulationThreadPool.getCurrent().submitAndWait(new Callable<NetElementID>()
            {
                @Override
                public NetElementID call() throws Exception {
                    return ((Place) _object).getID();
                }
            });
        try {
            return future.get();
        } catch (InterruptedException e) {
            LOGGER.error("Timeout while waiting for simulation thread to finish", e);
        } catch (ExecutionException e) {
            LOGGER.error("Simulation thread threw an exception", e);
        }

        // We should never return nothing but some error occured befor.
        return null;

    }

    /**
     * Returns the place, if the caller knows that
     * this is the local representation. This is required for setting breakpoints.
     * @return The place.
     */
    public Place getPlace() {
        return (Place) _object;
    }
}