package com.ssm.core.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URLEncoder;

@Slf4j
@Component
public class FtpUtils {

//    public FTPClient ftpClient = null;
//
//    /**
//     * 初始化ftp服务器
//     */
//    public void initFtpClient() {
//        ftpClient = new FTPClient();
//        ftpClient.setControlEncoding("utf-8");
//        try {
//            log.info("connecting...ftp服务器:"+ FtpConfig.hostname+":"+FtpConfig.port);
//            ftpClient.connect(FtpConfig.hostname, FtpConfig.port); //连接ftp服务器
//            ftpClient.login(FtpConfig.username, FtpConfig.password); //登录ftp服务器
//            int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
//            if(!FTPReply.isPositiveCompletion(replyCode)){
//                log.info("connect failed...ftp服务器:"+FtpConfig.hostname+":"+FtpConfig.port);
//            }
//            log.info("connect successfu...ftp服务器:"+FtpConfig.hostname+":"+FtpConfig.port);
//        }catch (MalformedURLException e) {
//            e.printStackTrace();
//        }catch (IOException e) {
//            e.printStackTrace();
//        }
//    }


    //天意达华为云（部署可用）
    //ftp服务器地址
    public String hostname = "110.41.6.1";//天懿达
    //ftp服务器端口号
    public Integer port = 21;//天懿达
    //ftp登录账号
    public String username = "ftp_server";//天懿达
    //ftp登录密码
    public String password = "tyd@2020";//天懿达


//    public String hostname = "121.37.192.186";//公司
//    //ftp服务器端口号
//    public Integer port = 21;//公司
//    //ftp登录账号
//    public String username = "ftpuser";//公司
//    //ftp登录密码
//    public String password = "123456789";//公司


    public FTPClient ftpClient = null;

    private static final String UTF8 = "UTF-8";

    /**
     * 初始化ftp服务器
     */
    public void initFtpClient() {
        ftpClient = new FTPClient();
        ftpClient.setControlEncoding("utf-8");
        ftpClient.enterLocalPassiveMode();

        try {
            log.info("connecting...ftp服务器:"+this.hostname+":"+this.port);
            ftpClient.connect(hostname, port); //连接ftp服务器
            ftpClient.login(username, password); //登录ftp服务器

            ftpClient.enterLocalPassiveMode();
            int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
            if(!FTPReply.isPositiveCompletion(replyCode)){
                log.info("connect failed...ftp服务器:"+this.hostname+":"+this.port);
            }
            log.info("connect successfu...ftp服务器:"+this.hostname+":"+this.port);
        }catch (MalformedURLException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件
     * @param pathname ftp服务保存地址
     * @param fileName 上传到ftp的文件名
     * @param originfilename 待上传文件的名称（绝对地址） *
     * @return
     */
    public boolean uploadFile( String pathname, String fileName,String originfilename){
        boolean flag = false;
        InputStream inputStream = null;
        try{
            log.info("开始上传文件");
            inputStream = new FileInputStream(new File(originfilename));
            initFtpClient();
            ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
            CreateDirecroty(pathname);
//            ftpClient.makeDirectory(pathname);
//            ftpClient.changeWorkingDirectory(pathname);
            ftpClient.storeFile(fileName, inputStream);
            inputStream.close();
            ftpClient.logout();
            flag = true;
            log.info("上传文件成功");
        }catch (Exception e) {
            log.info("上传文件失败",e);
            e.printStackTrace();
        }finally{
            if(ftpClient.isConnected()){
                try{
                    ftpClient.disconnect();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
            if(null != inputStream){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }
    /**
     * 上传文件
     * @param pathname ftp服务保存地址
     * @param fileName 上传到ftp的文件名
     * @param inputStream 输入文件流
     * @return
     */
    public boolean uploadFile( String pathname, String fileName,InputStream inputStream) throws IOException {
        boolean flag = false;
        try{
            log.info("开始上传文件");
            initFtpClient();
            ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
            CreateDirecroty(pathname);
//            ftpClient.enterLocalActiveMode();//主动模式
            ftpClient.enterLocalPassiveMode();//被动模式
            ftpClient.setFileTransferMode(ftpClient.STREAM_TRANSFER_MODE);
            flag = ftpClient.storeFile(fileName, inputStream);
            inputStream.close();
            ftpClient.logout();
            if (flag) {
                log.info("上传文件成功");
            }else {
                log.info("上传文件失败");

            }

        }catch (Exception e) {
            log.info("上传文件失败",e);
            e.printStackTrace();
        }finally{
            if(ftpClient.isConnected()){
                ftpClient.disconnect();
            }
            if(null != inputStream){
                inputStream.close();
            }
        }
        return flag;
    }
    //改变目录路径
    public boolean changeWorkingDirectory(String directory) throws IOException {
        boolean flag = true;

        flag = ftpClient.changeWorkingDirectory(directory);

        return flag;
    }

    //创建多层目录文件，如果有ftp服务器已存在该文件，则不创建，如果无，则创建
    public boolean CreateDirecroty(String remote) throws IOException {
        boolean success = true;
        String directory = remote + "/";
        // 如果远程目录不存在，则递归创建远程服务器目录
        if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory))) {
            int start = 0;
            int end = 0;
            if (directory.startsWith("/")) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf("/", start);
            String path = "";
            String paths = "";
            while (true) {
                String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
                path = path + "/" + subDirectory;
                if (!existFile(path)) {
                    if (makeDirectory(subDirectory)) {
                        changeWorkingDirectory(subDirectory);
                    } else {
//                        log.info("创建目录[" + subDirectory + "]失败");
                        changeWorkingDirectory(subDirectory);
                    }
                } else {
                    changeWorkingDirectory(subDirectory);
                }

                paths = paths + "/" + subDirectory;
                start = end + 1;
                end = directory.indexOf("/", start);
                // 检查所有目录是否创建完毕
                if (end <= start) {
                    break;
                }
            }
        }
        return success;
    }

    //判断ftp服务器文件是否存在
    public boolean existFile(String path) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpClient.listFiles(path);
        if (ftpFileArr.length > 0) {
            flag = true;
        }
        return flag;
    }
    //创建目录
    public boolean makeDirectory(String dir) throws IOException {
        boolean flag = true;
        flag = ftpClient.makeDirectory(dir);
//        if (flag) {
//            log.info("创建文件夹" + dir + " 成功！");
//
//        } else {
//            log.info("创建文件夹" + dir + " 失败！");
//        }
        return flag;
    }

    /** * 下载文件 *
     * @param pathname FTP服务器文件目录 *
     * @param filename 文件名称 *
     * @param localpath 下载后的文件路径 *
     * @return */
    public  boolean downloadFile(String pathname, String filename, String localpath) throws IOException {
        boolean flag = false;
        OutputStream os=null;
        try {
            log.info("开始下载文件");
            initFtpClient();
            //切换FTP目录
            ftpClient.changeWorkingDirectory(pathname);
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for(FTPFile file : ftpFiles){
                if(filename.equalsIgnoreCase(file.getName())){
                    File localFile = new File(localpath + "/" + file.getName());
                    os = new FileOutputStream(localFile);
                    ftpClient.retrieveFile(file.getName(), os);
                    os.close();
                }
            }
            ftpClient.logout();
            flag = true;
//            log.info("下载文件成功");
//        } catch (Exception e) {
//            log.info("下载文件失败");
//            e.printStackTrace();
        } finally{
            if(ftpClient.isConnected()){
                try{
                    ftpClient.disconnect();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
            if(null != os){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }

    public byte[] download(String pathname,String filename) throws IOException {
        OutputStream os=null;
        byte[] bytes = null;
        try {
//            log.info("开始下载文件");
            initFtpClient();
            //切换FTP目录
            ftpClient.changeWorkingDirectory(pathname);
            String remoteAbsoluteFile = new String(filename.getBytes("GBK"),"ISO8859-1");
            InputStream in = null;
            // 下载文件
            ftpClient.setBufferSize(1024);
            ftpClient.setControlEncoding("UTF-8");
            ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
            in = ftpClient.retrieveFileStream(remoteAbsoluteFile);
            bytes = input2byte(in);
//            log.info("下载文件成功");

//        } catch (Exception e) {
//            log.info("下载文件失败");
//            e.printStackTrace();
        } finally{
            if(ftpClient.isConnected()){
                try{
                    ftpClient.disconnect();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
        return bytes;
    }

    public byte[] input2byte(InputStream inStream) throws IOException {
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] buff = new byte[1024];
        int rc = 0;
        while ((rc = inStream.read(buff)) > 0) {
            swapStream.write(buff, 0, rc);
        }
        byte[] in2b = swapStream.toByteArray();
        swapStream.close();
        return in2b;
    }

    /** * 删除文件 *
     * @param pathname FTP服务器保存目录 *
     * @param filename 要删除的文件名称 *
     * @return */
    public boolean deleteFile(String pathname, String filename) throws IOException {
        boolean flag = false;
        try {
            log.info("开始删除文件");
            initFtpClient();
            //切换FTP目录
            ftpClient.changeWorkingDirectory(pathname);
            ftpClient.dele(filename);
            ftpClient.logout();
            flag = true;
//            log.info("删除文件成功");
//        } catch (Exception e) {
//            log.info("删除文件失败");
//            logger.error("");
        } finally {
            if(ftpClient.isConnected()){
                try{
                    ftpClient.disconnect();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
        return flag;
    }


    /**
     * 下载文件名重新编码
     *
     * @param request  请求对象
     * @param fileName 文件名
     * @return 编码后的文件名
     */
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) {
        final String agent = request.getHeader("USER-AGENT");
        String filename = fileName;
        try {
            if (agent.contains("MSIE")) {
                // IE浏览器
                filename = URLEncoder.encode(filename, UTF8);
                filename = filename.replace("+", " ");
            } else if (agent.contains("Firefox")) {
                // 火狐浏览器
                filename = new String(fileName.getBytes(), "ISO8859-1");
            } else if (agent.contains("Chrome")) {
                // google浏览器
                filename = URLEncoder.encode(filename, UTF8);
            } else {
                // 其它浏览器
                filename = URLEncoder.encode(filename, UTF8);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return filename;
    }

    public static void main(String[] args) {
        FtpUtils ftp =new FtpUtils();
        ftp.uploadFile("", "123.jpg", "C:\\Users\\Administrator\\Desktop\\timg.jpg");
        try {
            ftp.downloadFile("", "123.jpg", "C:\\Users\\Administrator\\Desktop");
        } catch (IOException e) {
            e.printStackTrace();
        }
//        ftp.deleteFile("ftpFile/data", "123.docx");
        log.info("ok");
    }
}
