/*
 * Created on 26 marzo 2004, 13.37
 */

package qms.queue.actions;
import qms.queue.*;
import qms.group.*;
import qms.util.*;
import java.util.*;
import qms.messages.*;
/**
 * Copia un nodo su di un altro nodo
 * @author  Enrico
 */
public class BulkCopyAction implements Action, WaitingAction, MessageListener{
    
    protected Node node;
    protected Controller controller;
    protected boolean finished;
    protected boolean sending_finished;
    protected boolean waiting;
    protected boolean started;
    protected int sent_count;
    protected int required_count;
    protected WaitingAction waiter;
    
    public BulkCopyAction(Controller controller, Node node, WaitingAction waiter) {
        this.controller = controller;
        this.finished = false;
        this.node = node;
        this.waiting = true;
        this.waiter = waiter;
        this.sent_count = 0;
        this.required_count = -1;
        this.started = false;
    }
    
    public boolean isFinished() {
        if (!finished) {
            if ((sending_finished) && (sent_count == required_count)) {
                finished = true;
                waiter.canStart();
            }
        }
        return finished;
    }
    
    public void runStep() {
        if (waiting) return;
        if (!started) {
            sending_finished = false;
            started = true;
            required_count = 0;
            QueuesManager queues = controller.getQueues();
            for (Iterator i = queues.queueNames(); i.hasNext(); ) {
                String qid = (String) i.next();
                MessageQueue queue = queues.getQueue(qid);
                                
                
                for (Iterator j = queue.getMessages().iterator(); j.hasNext(); ) {
                    
                    if (finished) return;
                    
                    Message msg = (Message) j.next();
                    
                    Message cont = new Message(
                            Node.getLocalNode().getName(),
                            node.getName(),
                            qid,
                            "group_bulk_copy_message",
                            msg.asXML());                    
                    cont.setListener(this);
                    required_count++;
                    controller.getMulticaster().castMessage(cont,node);
                }
                
            }
            
            // adesso gli passo tutta la conoscenza sui nodi
            Group nodes = controller.getGroup();
            for (Iterator i = nodes.iterator(); i.hasNext();) {
                Node peer = (Node) i.next();
                Message cont = new Message(
                            peer.getName(),
                            node.getName(),
                            QueuesManager.GROUP_QUEUE_ID,
                            "group_node_exists",
                            peer.getAccessPoint().toString());                    
                cont.setListener(this);
                required_count++;
                controller.getMulticaster().castMessage(cont,node);
            }
            
            
            sending_finished = true;                        
        }
    }
    public String toString() { return "bulk copy on "+node; }
    
    public void canStart() {
        waiting = false;
    }
    
    public void notifyMessageDelivered(Message who, boolean status) {        
        //Logger.log("BC received "+status+" notification of message "+sent_count+"/"+required_count);
        if (status) {
            sent_count++;                        
        } else {            
            finished = true;
            waiter.cancel();
        }
    }
    public void cancel() {
        finished = true;
        waiter.cancel();
    }
    public void notifyNodeRemoved(Node n) {        
    }    
}
