package de.renew.net;

import java.util.ConcurrentModificationException;
import java.util.Set;
import java.util.WeakHashMap;


/**
 * The net list class keeps track of all well known nets.
 * <p>
 * Accesses to the net list are synchronized to forbid concurrent updates.
 * No special actions must be taken on the caller side.
 * No deadlocks are possible.
 */
public class NetList {
    private static final WeakHashMap<Net, Object> NETS = new WeakHashMap<>();

    /**
     * This is an entirely static class.
     * No instance creation is allowed.
     */
    private NetList() {}

    /**
     * Register a net. If the net has already been registered, ignore.
     *
     * @param net the net to be registered
     */
    public static synchronized void add(Net net) {
        NETS.put(net, null);
    }

    /**
     * Create a snapshot of the list of registered net.
     * The nets are returned in a arbitrary order.
     *
     * @return an array that references all well-known nets
     */
    public static synchronized Net[] getAll() {
        while (true) {
            try {
                Set<Net> keySet = NETS.keySet();
                Net[] result = new Net[keySet.size()];
                int index = 0;

                for (Net net : keySet) {
                    result[index++] = net;
                }

                return result;
            } catch (ConcurrentModificationException e) {
                // Nets changed due to garbage collection, retry
            }
        }
    }
}