package indi.qiaolin.test.ureport.ftp;

import indi.qiaolin.test.ureport.exception.ConnectionPoolException;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.PoolableObjectFactory;

import javax.annotation.PreDestroy;
import java.util.NoSuchElementException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 *  FTP 客户端连接池
 * @author qiaolin
 * @version 2018年5月9日
 *
 */

public class FTPClientPool implements ObjectPool<FTPClient>{
	private FTPClientFactory factory;

	private BlockingQueue<FTPClient> pool;
	
	public FTPClientPool(FTPClientFactory factory) {
		this(10, factory);
	} 
	
	public FTPClientPool(int maxPoolSize, FTPClientFactory factory){
		this.factory = factory;
		this.pool = new ArrayBlockingQueue<>(maxPoolSize * 2); 
		try {
			for(int i = 0; i < maxPoolSize; i++){
			      addObject();
			 }
		} catch (Exception e) {
			e.printStackTrace();
			throw new ConnectionPoolException("FTP 连接池创建失败!");
		}
	}
	
	/**
	 *  添加对象到连接池
	 */
	@Override
	public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
		pool.offer(factory.makeObject(), 3, TimeUnit.SECONDS );
	}

	/**
	 *  从连接池中取出一个对象
	 */
	@Override
	public FTPClient borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
		FTPClient ftpClient = pool.take();
		if(ftpClient == null){
			ftpClient = factory.makeObject();
			addObject();
		}else if(!factory.validateObject(ftpClient)){
			// 从连接池中失效
			invalidateObject(ftpClient);
			// 制造新的对象,并添加到池中
			ftpClient = factory.makeObject();
			addObject();
		}
		return ftpClient;
	}
	
	/**
	 *   归还一个对象到连接池中
	 */
	@Override
	public void returnObject(FTPClient ftpClient) throws Exception {
		if(ftpClient != null && !pool.offer(ftpClient, 3, TimeUnit.SECONDS)){
			factory.destroyObject(ftpClient);
		}
		
	}
	
	/**
	 * 关闭对象池,清理内存释放资源等
	 */
	@Override
	@PreDestroy 
	public void close() throws Exception {
		while(pool.size() > 0){
			FTPClient ftpClient = pool.take();
			factory.destroyObject(ftpClient);
		}
	}
	
	/**
	 *  从连接池中移除一个对象
	 */
	@Override
	public void invalidateObject(FTPClient client) throws Exception {
		pool.remove(client);
	}
	
	/**
	 * 需要一个工厂来制造池中的对象
	 */
	@Override
	public void setFactory(PoolableObjectFactory<FTPClient> factory)
			throws IllegalStateException, UnsupportedOperationException {
	}
	
	
	
	@Override
	public void clear() throws Exception, UnsupportedOperationException {
		
	}

	@Override
	public int getNumActive() throws UnsupportedOperationException {
		return 0;
	}

	@Override
	public int getNumIdle() throws UnsupportedOperationException {
		return 0;
	}



	
	

}