/*
 * Created on 21-Nov-2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package uk.ac.roe.wfau;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import net.alanmaxwell.sql.WSASQLRetrieverThread;

/**
 * @author mar
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class QueueManager {
    static Logger  logger = Logger.getLogger("wsa.simple");
    public static int numSSARunners=0;
    public static int maxNumSSARunners=2;
    public int numWSARunners=0;
    public static boolean queueStopped=false;
    public static Thread [] threadArray ;
    public static boolean isQStopped=false;
    static int maxNoQRunners=2;
    static int runnerID=0;
    public static Map threadHashMap=new HashMap() ;
    public static Map qIDMap=new HashMap() ;
    
    // runner[1]=new Thread(retrieverThread);
    
   /* WSASQLRetrieverThread retrieverThread = null ; 
    String str;
    runner[1] = new Thread(retrieverThread);
    */
    
    public synchronized static void setQIDStatus (int qID, int qStatus){
        qIDMap.put(new Integer(qID),new Integer(qStatus));
    }
    
    public static void removeQIDStatus(int qID) {
        qIDMap.remove(new Integer(qID));
    }
    
    public static int getQIDStatus(int qID) {
        try {
        return ((Integer)qIDMap.get(new Integer(qID))).intValue();
        }
        catch (NullPointerException npe){
            return -1;
        }
    }
    
    static void removeFromQ(int rID){
        logger.info("removing runner "+rID);
        threadHashMap.remove(new Integer(rID));
        
        logger.info("no of runner threads "+threadHashMap.size());        
    }
    
    public synchronized static void startQ (){
        logger.info("starting Q");
        for (int i=0; i < maxNoQRunners; i++) {
        if (threadHashMap.size() < maxNoQRunners) {
            runnerID++;
            logger.info("starting runner "+runnerID);
            startRunner(runnerID);
        }        
        }
    }
    
    public synchronized static void clearQ (){
        try {
        threadHashMap.clear();
        }
        catch (Exception e) {
            
        }
    }
    
    public static void nudgeRunners(){
        if (!isQStopped) {
        // see if there's any runners and interrupt the sleeping ones
        Set keys = threadHashMap.keySet();      
        Iterator keyIter = keys.iterator();
        Thread tempThread;
        boolean foundDeadRunners=false;
        
        while (keyIter.hasNext()) {
            Object key = keyIter.next();  // Get the next key.
            tempThread=(Thread)threadHashMap.get(key);
            if (tempThread.isAlive()) {
                
                logger.info(((Integer)key).intValue()+" is alive");
                logger.info("interupt runner");
                tempThread.interrupt();
                
            }
            else {
                logger.info("found a dead runner,removing runner thread"+((Integer)key).intValue());
                removeFromQ(((Integer)key).intValue());
                foundDeadRunners=true;
                
            }
        }
        keys=null;
        keyIter=null;
        tempThread=null;
        logger.info("seeing if Q needs starting");
        startQ();
        logger.info("nudging runners");
        
        
        }      
        
    }
    public static void startRunner(int id) {
        logger.info("begin startrunner");
        QueueRunner runnerThread =new QueueRunner(id);
        
        Thread rThread=new Thread(runnerThread);
        threadHashMap.put(new Integer(id),rThread);
        rThread.start();
        rThread=null;
        runnerThread=null;
        logger.info("end startrunner "+id);
        

}
    
    public static synchronized int getNumRunners(int i) {
        QueueRunner runnerThread =null;
        
        
        if (numSSARunners < maxNumSSARunners && i >0) {
            numSSARunners=numSSARunners+i;
            return numSSARunners-1;
        }
        return numSSARunners;
    }
    //public static synchronized set
    

    
    
    
    /*
    public static void startRunner(int id) {
        
        QueueRunner runnerThread =new QueueRunner(id);
        threadArray[id]=new Thread(runnerThread);
        threadArray[id].start();
}
*/
}