/*
 * QueuesManager.java
 *
 * Created on 5 marzo 2004, 20.19
 */

package qms.messages;
import java.util.*;
import qms.group.*;
import qms.util.*;
import qms.messages.*;
/**
 * Gestisce tutte le code
 * @author  Enrico
 */
public class QueuesManager implements QueueListener {
    protected Map queues;
    protected Group nodes;    
    
    public final static String SYSTEM_QUEUE_ID = "system";
    public final static String GROUP_QUEUE_ID = "group";
    
    public QueuesManager(Group nodes) {
        queues = new HashMap();
        this.nodes = nodes;
        createQueue(SYSTEM_QUEUE_ID).addListener(this);
    }
    /**
     * Ottiene una coda, se non esiste la crea
     */
    public MessageQueue getQueue(String id) {
        MessageQueue result =  (MessageQueue) queues.get(id);
        return createQueue(id);                
    }
    /**
     * Crea una coda
     */
    public synchronized MessageQueue createQueue(String id) {
        // controlliamo che non sia già stata creata...
        MessageQueue result =  (MessageQueue) queues.get(id);
        if (result != null) return result;
        
        // creiamo...
        MessageQueue queue = new MessageQueue(id,nodes);
        queues.put(id,queue);
        return queue;
    }
    /**
     * Elimina una coda ed informa gli interessati 
     */
    public synchronized void deleteQueue(String id) {
        MessageQueue q = (MessageQueue) queues.get(id);
        if (q != null) {
            queues.remove(id);        
            q.notifyQueueDestroyed();
        }
    }
    /**
     * Iterazione sui nomi (String) delle code
     */
    public Iterator queueNames() {return queues.keySet().iterator(); }
        
    /**
     * Riconosce quando un messaggi è stato aggiunto alla coda "system"
     */
    public void messageAdded(MessageQueue queue, Message msg) {
        if (queue.getId().equals(SYSTEM_QUEUE_ID)) {
            if (msg.getType().equals("system_delete_queue")) {
                String qid = msg.getBody();
                Logger.log("Deleting queue "+qid);
                deleteQueue(qid);
                queue.removeMessage(msg.getId());
            }
        }
    }
    
    public void messageRemoved(MessageQueue queue, Message msg) {
    }
    /**
     * Crea un nuovo ID per un lock. Non ha effetti collaterali
     */
    public static String createNewLockID() {
        return "lck"+System.currentTimeMillis();
    }
    /**
     * rimpalla la notizia che un nodo è stato rimosso del gruppo a tutte le code
     */
    public void notifyNodeRemoved(Node n) {
        for (Iterator i = queueNames(); i.hasNext(); ) {
            String qid = (String) i.next();
            MessageQueue q = getQueue(qid);
            q.notifyNodeRemoved(n);
        }
    }
}
