/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jserver.communityserver.threading;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import com.l2jserver.communityserver.Config;

/**
 * Simple wrapper class to run packets on a ThreadPoolExecutor.<br>
 * PriorityThreadFactory has been imported from L2J Server, coded by Wooden
 * 
 * @author DrHouse - L2JServer Team
 *
 */
public class ThreadPoolManager
{
	private static ThreadPoolExecutor _mainPool;
	
	
	public static synchronized final boolean init()
	{
		if (_mainPool != null)
			return false;
		
		_mainPool = new ThreadPoolExecutor(Config.GENERAL_THREAD_CORE_SIZE, Config.GENERAL_THREAD_CORE_SIZE + 2, 5L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new PriorityThreadFactory("CommunityServer Executor pool", Thread.NORM_PRIORITY));
		_mainPool.prestartAllCoreThreads();
		return true;
	}
	
	public final static void execute(Runnable task)
	{
		_mainPool.execute(task);
	}
	
	private static class PriorityThreadFactory implements ThreadFactory
	{
		private int _prio;
		private String _name;
		private AtomicInteger _threadNumber = new AtomicInteger(1);
		private ThreadGroup _group;
		
		public PriorityThreadFactory(String name, int prio)
		{
			_prio = prio;
			_name = name;
			_group = new ThreadGroup(_name);
		}
		
		/* (non-Javadoc)
		 * @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
		 */
		public Thread newThread(Runnable r)
		{
			Thread t = new Thread(_group, r);
			t.setName(_name + "-" + _threadNumber.getAndIncrement());
			t.setPriority(_prio);
			return t;
		}
		
		@SuppressWarnings("unused")
		public ThreadGroup getGroup()
		{
			return _group;
		}
	}
}