package com.bcxin.signature.util.ftp;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class FtpClientPool {
    private static final Logger logger = LoggerFactory.getLogger(FtpClientPool.class);
    private final BlockingQueue<FTPClient> pool = new LinkedBlockingQueue<>();
    private final String server, user, password;
    private final int port;

    public FtpClientPool(int size, String server, int port, String user, String password){
        this.server = server;
        this.port = port;
        this.user = user;
        this.password = password;
        // 初始化5个连接
        for (int i = 0; i < size; i++) {
            try {
                FTPClient ftpClient = new FTPClient();
                initConnect(ftpClient, this.server, this.port, this.user, this.password);
                pool.add(ftpClient);
            } catch (Exception ex) {
                System.err.println("Failed to initialze the ftp client");
            }
        }
    }

    public synchronized FTPClient borrowConnection() {
        FTPClient ftpClient = null;
        do {
            ftpClient = pool.poll();

            if (!ftpClient.isConnected()) {
                try {
                    initConnect(ftpClient, this.server, this.port, this.user, this.password);
                } catch (Exception ex) {
                    logger.error("{} reconnect-Failed to initialze the ftp client", ftpClient.hashCode(),ex);
                }
            }
            if (ftpClient != null) {
                break;
            }

            try {
                Thread.sleep(500);
            } catch (Exception ex) {
            }
        } while (ftpClient == null); // 从池中取出连接

        return ftpClient;
    }

    public synchronized void returnConnection(FTPClient conn) {
        if (conn != null) {
            try {
                conn.disconnect();
            } catch (Exception ex) {
            }

            pool.offer(conn); // 归还连接
        }
    }

    public void closeAll() throws IOException {
        for (FTPClient conn : pool) conn.disconnect();
    }

    private static void initConnect(FTPClient ftpClient, String host, int port, String user, String password) throws IOException {
        try {
            if(!ftpClient.isConnected()) {
                ftpClient.connect(host, port);
                ftpClient.setBufferSize(1024 * 1024); // 1MB缓冲区
                ftpClient.setControlKeepAliveReplyTimeout(5 * 60 * 1000);

                /*
                ftpClient.addProtocolCommandListener(new PrintCommandListener(
                        new PrintWriter(System.err), true));  // 打印所有FTP命令

                 */
            }
        } catch (UnknownHostException ex) {
            throw new IOException("Can't find FTP server '" + host + "'");
        }
        //被动模式
        ftpClient.enterLocalPassiveMode();
        int reply = ftpClient.getReplyCode();//220 连接成功
        if (!FTPReply.isPositiveCompletion(reply)) {
            disconnect();
            throw new IOException("Can't connect to server '" + host + "'");
        }
        if (!ftpClient.login(user, password)) {
            //is_connected = false;
            disconnect();
            throw new IOException("Can't login to server '" + host + "'");
        } else {
            //is_connected = true;
        }
    }

    public static void disconnect() throws IOException {
    }

    public FTPClient newFTPClient() throws IOException {
    	FTPClient ftpClient = new FTPClient();
        initConnect(ftpClient, this.server, this.port, this.user, this.password);

    	return ftpClient;
    }
}
