package com.inspect.base.core.sftp;

import com.alibaba.fastjson.JSONObject;
import com.inspect.base.core.constant.Color;
import com.inspect.base.core.exception.ServiceException;

import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Queue;
import javax.annotation.PostConstruct;
import javax.net.ssl.SSLContext;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPSClient;
import org.apache.commons.net.util.TrustManagerUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class SftpFactory {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private SftpLoginConfig sftpLoginConfig;
    public volatile Queue<FTPSClient> queue = new ArrayDeque<>();
    public int aliveNum = 20;
    public int initNum = 5;

    public synchronized FTPSClient getInstance() {
        return !this.queue.isEmpty() ? this.queue.remove() : null;
    }

    public void reset() {
        (new Thread(() -> {
            if (this.queue.size() < this.aliveNum) {
                try {
                    this.queue.add(this.connect());
                } catch (IOException var2) {
                    ;
                }

            }
        })).start();
    }

    @PostConstruct
    public void init() throws IOException {
        (new Thread(() -> {
            this.queue.clear();

            for (int i = 0; i < this.initNum; ++i) {
                FTPSClient ftps = null;

                try {
                    ftps = this.connect();
                    this.queue.add(ftps);
                } catch (IOException e) {
                    ;
                } catch (ServiceException e) {
                    if (!"Error".equals(e.getMessage())) {
                        throw e;
                    }
                }
            }

        })).start();
    }

    public FTPSClient connect() throws IOException {
        int maxRetries = 5;
        int retryCount = 0;
        long retryDelay = 1000L;
        while (retryCount < maxRetries) {
            boolean isImplicit = "true".equals(sftpLoginConfig.getIsImplicit());
            //boolean isImplicit = Boolean.getBoolean(sftpLoginConfig.getIsImplicit());
            logger.info(Color.MAGENTA + "[FTP] isImplicit: {}" + Color.END, isImplicit);
            FTPSClient ftps = new FTPSClient(isImplicit);
            try {
                ftps.setControlEncoding("UTF-8");
                ftps.connect(sftpLoginConfig.getIp(), Integer.parseInt(sftpLoginConfig.getPort()));
                boolean login = ftps.login(sftpLoginConfig.getUsername(), sftpLoginConfig.getPassword());
                if (!login) {
                    throw new ServiceException("LOGIN TO FTP FAIL!");
                } else {
                    return ftps;
                }
            } catch (Exception e) {
                retryCount++;
                logger.error("[FTP] CONN FAIL: {}, (attempt {}/{}): CAUSE: {}",
                        JSONObject.toJSONString(sftpLoginConfig), retryCount, maxRetries, e.getMessage());

                // 清理资源
                if (ftps != null && ftps.isConnected()) {
                    try {
                        ftps.disconnect();
                    } catch (IOException ex) {
                        logger.debug("[FTP] Error during disconnect", ex);
                    }
                }

                if (retryCount < maxRetries) {
                    try {
                        logger.info("[FTP] Retrying in {} ms", retryDelay);
                        Thread.sleep(retryDelay);
                        retryDelay *= 2;
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new IOException("Interrupted during retry", ie);
                    }
                } else {
                    throw new IOException("Failed to connect after " + maxRetries + " attempts", e);
                }
            }
        }
        throw new IOException("Unexpected error in connection process");
    }

    public static void main(String[] args) {

        for (int i = 0; i < 100; i++) {
            try {
                FTPSClient ftps = new FTPSClient(true);
                ftps.setControlEncoding("UTF-8");
                ftps.connect("192.168.1.198", 990);
                //ftps.connect("192.168.1.116", 1990);
                boolean login = ftps.login("ftpuser", "atia2018");
                System.out.println("ss:" + login);


            } catch (Exception var5) {

                var5.printStackTrace();
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException var4) {
                    ;
                }


            }
        }

    }
}
