/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.cqcis.com</a>
 */
package com.crunii.micro.common.ftp;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

/**
 * @author 田平 create 2016-6-14上午11:48:47
 */
@Slf4j
public class FTPClientFactory extends BasePooledObjectFactory<FTPClient> {
	private FTPClientConfig clientConfig;
	private String host;
	private int port;
	private String username;
	private String password;
	private int timeout = 30000;// 默认30秒
	private int fileType = FTP.BINARY_FILE_TYPE;// 文件类型
	private int bufferSize = 1024 * 1024 * 20;// 20M
	private String systemType = FTPClientConfig.SYST_UNIX;
	private String encoding = "GBK";

	public static void main(String[] args) throws Exception {
		FTPClientFactory clientFactory = new FTPClientFactory();
		clientFactory.setHost("136.3.243.201");
		clientFactory.setPort(21);
		clientFactory.setUsername("cqpf");
		clientFactory.setPassword("cqpf");
		GenericObjectPool<FTPClient> pool = new GenericObjectPool<FTPClient>(clientFactory, new GenericObjectPoolConfig());
		FTPClient client = pool.borrowObject();
		client.changeWorkingDirectory("/home/cqpf/tomcat-6.0.16-pfjob/ods/pf/");
		System.out.println(client.deleteFile("test.txt"));
		// client.storeFile("test.txt", new ByteArrayInputStream("中国aaaa1\n".getBytes("GBK")));
		// client.appendFile("test.txt", new ByteArrayInputStream("中国aaaa2\n".getBytes("GBK")));
		pool.returnObject(client);
		pool.close();
	}

	/**
	 * @see BasePooledObjectFactory#create()
	 */
	@Override
	public FTPClient create() throws Exception {
		FTPClient ftp = new FTPClient();

		if (clientConfig != null) {
			ftp.configure(clientConfig);
		} else {
			FTPClientConfig ftpClientConfig = new FTPClientConfig(systemType);
			ftp.configure(ftpClientConfig);
		}
		ftp.connect(host, port);
		int reply = ftp.getReplyCode();
		log.info("Connect FTP server:" + host + ",port:" + port + ",replyCode:" + ftp.getReplyCode() + ",replyString:" + ftp.getReplyString());
		if (!FTPReply.isPositiveCompletion(reply)) {
			if (ftp.isConnected()) {
				ftp.disconnect();
			}
			throw new RuntimeException("FTP server refused connection" + host + ",replyString:" + ftp.getReplyString());
		}
		boolean success = ftp.login(username, password);

		ftp.setSoTimeout(timeout);
		ftp.setBufferSize(bufferSize);
		ftp.setFileType(fileType);
		ftp.enterLocalPassiveMode();// 被动模式
		ftp.setControlEncoding(encoding);
		if (!success) {
			if (ftp.isConnected()) {
				ftp.disconnect();
			}
			throw new RuntimeException(
					"FTP server login failure!server:" + host + ",username:" + username + ",password:" + password + ",replyString:" + ftp
							.getReplyString());
		}

		return ftp;
	}

	/**
	 * @see BasePooledObjectFactory#wrap(Object)
	 */
	@Override
	public PooledObject<FTPClient> wrap(FTPClient obj) {
		return new DefaultPooledObject<FTPClient>(obj);
	}

	public boolean validateObject(PooledObject<FTPClient> p) {
		boolean available = p.getObject().isAvailable();
		boolean connected = p.getObject().isConnected();
		// log.info("available:" + available + ",connected:" + connected);
		return available && connected;
	}

	public void destroyObject(PooledObject<FTPClient> p) throws Exception {
		if (p != null) {
			FTPClient ftp = p.getObject();
			if (ftp.isConnected()) {
				ftp.disconnect();
			}
		}
	}

	/**
	 * @param clientConfig the clientConfig to set
	 */
	public void setClientConfig(FTPClientConfig clientConfig) {
		this.clientConfig = clientConfig;
	}

	/**
	 * @return the server
	 */
	public String getHost() {
		return host;
	}

	/**
	 * @param host the server to set
	 */
	public void setHost(String host) {
		this.host = host;
	}

	/**
	 * @return the port
	 */
	public int getPort() {
		return port;
	}

	/**
	 * @param port the port to set
	 */
	public void setPort(int port) {
		this.port = port;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the clientConfig
	 */
	public FTPClientConfig getClientConfig() {
		return clientConfig;
	}

	/**
	 * @return the timeout
	 */
	public int getTimeout() {
		return timeout;
	}

	/**
	 * @param timeout the timeout to set
	 */
	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	/**
	 * @return the fileType
	 */
	public int getFileType() {
		return fileType;
	}

	/**
	 * @param fileType the fileType to set
	 */
	public void setFileType(int fileType) {
		this.fileType = fileType;
	}

	/**
	 * @return the bufferSize
	 */
	public int getBufferSize() {
		return bufferSize;
	}

	/**
	 * @param bufferSize the bufferSize to set
	 */
	public void setBufferSize(int bufferSize) {
		this.bufferSize = bufferSize;
	}

	/**
	 * @return the systemType
	 */
	public String getSystemType() {
		return systemType;
	}

	/**
	 * @param systemType the systemType to set
	 */
	public void setSystemType(String systemType) {
		this.systemType = systemType;
	}

	/**
	 * @return the encoding
	 */
	public String getEncoding() {
		return encoding;
	}

	/**
	 * @param encoding the encoding to set
	 */
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

}
