package de.renew.shadowcompiler;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;

import de.renew.net.Place;
import de.renew.net.Transition;
import de.renew.simulatorontology.shadow.ShadowPlace;
import de.renew.simulatorontology.shadow.ShadowTransition;

/**
 * Provides context-based lookup for {@link Place} and {@link Transition}
 * objects using their associated context keys from a {@link ShadowLookup}.
 * <p>
 * This class builds a map between context objects and their corresponding
 * {@code Place} or {@code Transition} instances at construction time.
 */
public class ContextLookup {
    private final Hashtable<Object, Serializable> _map;

    /**
     * Creates a new {@code ContextLookup} by extracting context mappings
     * from the given {@code ShadowLookup}. The mappings associate shadow
     * objects with their corresponding {@link Place} and {@link Transition}
     * instances.
     *
     * @param shadowLookup the shadow lookup to extract context mappings from
     */
    public ContextLookup(ShadowLookup shadowLookup) {
        _map = new Hashtable<>();

        Enumeration<ShadowPlace> places = shadowLookup.allPlaces();
        while (places.hasMoreElements()) {
            ShadowPlace shadowPlace = places.nextElement();
            Place place = shadowLookup.get(shadowPlace);
            _map.put(shadowPlace.getContext(), place);
        }

        Enumeration<ShadowTransition> transitions = shadowLookup.allTransitions();
        while (transitions.hasMoreElements()) {
            ShadowTransition shadowTransition = transitions.nextElement();
            Transition transition = shadowLookup.get(shadowTransition);
            _map.put(shadowTransition.getContext(), transition);
        }
    }

    /**
     * Returns the {@code Place} associated with the given context object.
     *
     * @param context the context key to look up
     * @return the corresponding {@code Place}, or {@code null} if not found
     */
    public Place getPlace(Object context) {
        return (Place) _map.get(context);
    }

    /**
     * Returns the {@code Transition} associated with the given context object.
     *
     * @param context the context key to look up
     * @return the corresponding {@code Transition}, or {@code null} if not found
     */
    public Transition getTransition(Object context) {
        return (Transition) _map.get(context);
    }

    /**
     * Returns the full context-to-object mapping.
     *
     * @return a {@code Hashtable} containing context-object mappings
     */
    public Hashtable<Object, Serializable> getMap() {
        return _map;
    }
}