package net.jueb.util4j.queue.queueExecutor.queueGroup.impl;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import net.jueb.util4j.queue.queueExecutor.queue.QueueExecutor;
import net.jueb.util4j.queue.queueExecutor.queueGroup.IndexQueueGroupManager;

public class ArrayIndexQueueManager implements IndexQueueGroupManager{
	/**
	 * 最大队列插槽数
	 */
	public static final int MAX_SOLT_COUNT = 0xFFFF;

	/**
	 * 队列插槽
	 */
	private final SoltQueue[] solts = new SoltQueue[MAX_SOLT_COUNT + 1];

	/**
	 * 队列别名
	 */
	private final String[] soltAlias = new String[solts.length];
	
	private final AtomicLong totalCompleteTask=new AtomicLong();
	
	public ArrayIndexQueueManager() {
		init();
	}
	
	protected void init()
    {
		for(int i=0;i<solts.length;i++)
    	{
    		solts[i]=new SoltQueue(i);
    	}
    }
	
	/**
	 * 转换为插槽索引
	 * 
	 * @param solt
	 * @return
	 */
	protected final int convertIndex(short solt) {
		byte a = (byte) (solt >> 8 & 0xFF);// 高8位
		byte b = (byte) (solt & 0xFF);// 低8位
		int value = ((int) (a)) << 8 | (int) (b);
		return value & 0xffff;
	}

	public Iterator<QueueExecutor> iterator() {
		return new Iterator<QueueExecutor>() {
			int i = 0;

			@Override
			public boolean hasNext() {
				return i < solts.length;
			}

			@Override
			public QueueExecutor next() {
				return solts[i++];
			}
		};
	}

	public void execute(short solt, Runnable task) {
		if (task == null) {
			throw new RuntimeException("task is null");
		}
		getQueueExecutor(solt).execute(task);
	}

	public void execute(short solt, List<Runnable> tasks) {
		if (tasks == null) {
			throw new RuntimeException("tasks is null");
		}
		getQueueExecutor(solt).execute(tasks);
	}

	public void setAlias(short solt, String alias) {
		soltAlias[convertIndex(solt)] = alias;
	}

	public String getAlias(short solt) {
		return soltAlias[convertIndex(solt)];
	}

	public QueueExecutor getQueueExecutor(short solt) {
		int index = convertIndex(solt);
		return solts[index];
	}
	
	private volatile IndexGroupEventListener listener;
	
	public void setGroupEventListener(IndexGroupEventListener listener)
	{
		this.listener=listener;
	}
	
	protected void onQueueHandleTask(short solt,Runnable handleTask)
	{
		IndexGroupEventListener tmp=listener;
		if(tmp!=null)
		{
			tmp.onQueueHandleTask(solt, handleTask);
		}
	}
	
	public long getToalCompletedTaskCount(short solt) {
		int index = convertIndex(solt);
		return solts[index].getCompletedTaskCount().get();
	}

	/**
	 * 获取总完成任务数量
	 * @return
	 */
	public long getToalCompletedTaskCount() {
        return totalCompleteTask.get();
    }
	
	/**
	 * 插槽队列
	 * @author juebanlin
	 */
	private class SoltQueue extends RunnableQueueExecutor{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1711281918590904219L;
		private final int soltIndex;
		/**
	     * 此队列是否锁定/是否被线程占用
	     * 次属性仅供本类持有
	     */
	    private final AtomicBoolean isLock = new AtomicBoolean(false);
	    /**
	     * 此队列完成的任务数量
	     */
		private final AtomicLong completedTaskCount = new AtomicLong(0);
		
		public SoltQueue(int soltIndex) {
			super("SoltQueue-"+soltIndex);
			this.soltIndex=soltIndex;
			init();
		}
		
		@Override
		public String getQueueName() {
			return getAlias((short) soltIndex);
		}
		
		/**
		 * 初始化状态
		 */
		public void init(){
			isLock.set(false);
			completedTaskCount.set(0);
			super.clear();
		}
		
		public AtomicLong getCompletedTaskCount() {
			return completedTaskCount;
		}
		
		@Override
		protected void event_taskOfferAfter(boolean offeredSucceed) {
			super.event_taskOfferAfter(offeredSucceed);
			if(offeredSucceed)
			{
				if(isLock.compareAndSet(false, true))
			 	{//一个处理任务产生
					onQueueHandleTask((short)soltIndex,new SoltQueueProcessTask(this));
			 	}
			}
		}

		private class SoltQueueProcessTask implements Runnable{
	    	SoltQueue queue;
	    	public SoltQueueProcessTask(SoltQueue queue) {
	    		this.queue=queue;
			}
			@Override
			public void run() {
				try {
					handleQueueTask(queue);
				} finally {
					queue.isLock.set(false);
				}
			}
			
			 /**
	         * 处理队列任务
	         * @param queue
	         */
	        private void handleQueueTask(SoltQueue queue) {
	        	Thread thread=Thread.currentThread();
	        	for (;;) 
	            {
	        		Runnable task = queue.poll();
	            	if(task == null)
	                {//停止处理队列
	            		break;
	                }
	            	beforeExecute(thread, task);
	                boolean succeed = false;
	                try {
	                    task.run();
	                    queue.getCompletedTaskCount().incrementAndGet();
	                    totalCompleteTask.incrementAndGet();
	                    succeed = true;
	                    afterExecute(task, null);
	                } catch (RuntimeException e) {
	                    if (!succeed) {
	                        afterExecute(task, e);
	                    }
	                    throw e;
	                }
	            }
	        }
	    }
		
		protected void beforeExecute(Thread thread, Runnable task) {
			
		}

		protected void afterExecute(Runnable task,RuntimeException object) {
			
		}
	}
}
@@ -996,16 +996,30 @@
 %0D%0A%09 */%0D%0A
+%09@Deprecated%0D%0A
 %09protect
@@ -1043,16 +1043,20 @@
 ertIndex
+_old
 (short s
@@ -1189,24 +1189,24 @@
 (int) (b);%0D%0A
-
 %09%09return val
@@ -1218,24 +1218,157 @@
 0xffff;%0D%0A%09%7D%0D
+%0A%09/**%0D%0A%09 * %E8%BD%AC%E6%8D%A2%E4%B8%BA%E6%8F%92%E6%A7%BD%E7%B4%A2%E5%BC%95%0D%0A%09 * @param solt%0D%0A%09 * @return%0D%0A%09 */%0D%0A%09protected final int convertIndex(short solt) %7B%0D%0A%09%09return solt & 0xFFFF;%0D%0A%09%7D%0D
 %0A%0D%0A%09public I

优化Queue index索引转换