package im.zhaojun.common.util;
import im.zhaojun.system.model.Ftp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;

import javax.annotation.PostConstruct;
import java.io.*;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@SuppressWarnings("all")
@Component
public class FTPUtil {

    @Value("${ftp.host}")
    private String ftpHost ;
    private List<Ftp> ftps = new ArrayList<Ftp>();

    @PostConstruct
    private void initHostMap(){
        if(ftpHost==null){
            log.error("ftp�洢��δ���ã���������");
            log.error("ftp�洢��δ���ã���������");
            return;
        }



    }


    public static void downLoadFile(String path, OutputStream toClient) {
        BufferedInputStream bis = null;
        InputStream is = null;
        try {
            if (path.toUpperCase().indexOf("FTP") != -1) {
                String tempUrl = path;
                tempUrl = tempUrl.replaceAll("\\\\", "/");
                URL url = new URL(tempUrl);
                is = url.openStream();
                bis = new BufferedInputStream(is);
                IOUtils.copy(bis, toClient);
                return;
            }
        } catch (Exception e) {
            log.error("FTP����ͼƬ����", e);
        } finally {
            IOUtils.closeQuietly(toClient);
            IOUtils.closeQuietly(is);
            IOUtils.closeQuietly(bis);
        }
    }

    public static byte[] getFtpPicBytes(String path) {
        URL url = null;
        try {
            url = new URL(path);
        } catch (MalformedURLException e) {
            log.error("FTP URL error"+e.toString());
            return null;
        }
        byte[] buffer = null;
        try {
            InputStream is = url.openStream();
            if(null!=is) {
                ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
                byte[] b = new byte[1000];
                int n;
                while ((n = is.read(b)) != -1) {
                    bos.write(b, 0, n);
                }
                buffer = bos.toByteArray();
            }

        }catch (Exception e) {
            log.error("FTPerror", e);
        }
        return buffer;
    }

    public static boolean uploadFile(Ftp ftpUrl, String path, String filename, String inputImg)  {
        boolean flag = true;
        FTPClient ftpClient = null;
        ByteArrayInputStream input = null;
        try {
            if (inputImg == null) {
                return false;
            }
            //base64����
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] b_img = decoder.decodeBuffer(inputImg);
            input = new ByteArrayInputStream(b_img);
            ftpClient = connectServer(ftpUrl);
            //new ByteArrayInputStream
            if (ftpClient.isConnected()) {
                changeWorkingDirectory(ftpClient, path);
                flag = ftpClient.storeFile(filename, input);
                if (flag) {
//                    log.info("FTP�ϴ��ļ��ɹ���");
                } else {
                    flag = false;
                    log.info("FTP�ϴ��ļ�ʧ�ܣ�");
                }
            }
        } catch (Exception e) {
            flag = false;
            log.error("FTP�ļ��ϴ�ʧ�ܣ�", e.toString());
        } finally {
            IOUtils.closeQuietly(input);
            closeConnect(ftpClient);
        }
        return flag;
    }

    public static boolean uploadFile(Ftp ftpUrl, String path, String filename, InputStream input){
        boolean flag = true;
        FTPClient ftpClient = null;
        try {
            ftpClient = connectServer(ftpUrl);
            if (ftpClient.isConnected()) {
                changeWorkingDirectory(ftpClient, path);
                flag = ftpClient.storeFile(filename, input);
                if (flag) {
//                    log.info("FTP upload success��");
                } else {
                    log.info("FTP upload fail��");
                }
            } else {
                flag = false;
//                log.info("FTP server refused connection ��");
            }
        } catch (IOException e) {
            flag = false;
            log.error("FTP upload fail��", e);
        } catch (Exception e) {
            flag = false;
            log.error("FTP upload fail��", e);
        } finally {
            IOUtils.closeQuietly(input);
            closeConnect(ftpClient);
        }
        return flag;
    }

    /*
     * �õ������ļ��е�FTP��������ַ
     */
    public static String getFtpUrl(Ftp ftpUrl) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("ftp://");
        String ftpUsername = ftpUrl.getFtpUsername();
        if (ftpUsername != null && ftpUsername.trim().length() > 0) {
            buffer.append(ftpUsername);
            buffer.append(":");
            buffer.append(ftpUrl.getFtpPassword());
            buffer.append("@");
        }
        buffer.append(ftpUrl.getFtpIp());
        if (ftpUrl.getFtpPort() != null) {
            buffer.append(":");
            buffer.append(ftpUrl.getFtpPort());
        }
        buffer.append("/");
        return buffer.toString();
    }

    /**
     * @param ftpUrl
     * @return
     * @throws Exception
     * @description ɾ��ftp�ϵ��ļ�
     * @author sunw
     */
    public static boolean deleteFileFromFtpUrl(String ftpUrl) throws Exception {
        boolean flag = false;
        if (null == ftpUrl || StringUtils.isBlank(ftpUrl)) {
            throw new Exception("ftpUrl��Ϊ��");
        }
        Map<String, String> result = getFtpInfoMapByFullPath(ftpUrl);
        String ftpUser = result.get("ftpUser");
        String ftpPassword = result.get("ftpPassword");
        String ftpIp = result.get("ftpIp");
        String ftpPort = result.get("ftpPort");
        String fileName = result.get("fileName");
        String path = result.get("path");
        Ftp ftp = FTPUtil.getFtpUrlObj(ftpIp, ftpPort, ftpUser, ftpPassword);
        FTPClient ftpClient = connectServer(ftp);
        if (null == ftpClient) {
            throw new Exception("ftp��¼ʧ�� ");
        } else {
            String fullPath = (null == path || "".equals(path.trim())) ? fileName : (path + "/" + fileName);
            try {
                flag = ftpClient.deleteFile(fullPath);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return flag;

    }

    /**
     * @param ftpUrlStr
     * @return
     * @throws Exception
     * @author sunw ͨ��ͼƬ·��
     * ���ftpuser,ftppassword,ftpip,ftpport,��fpt�ϵ��ļ�·��,�ļ�realname
     */
    private static Map<String, String> getFtpInfoMapByFullPath(String ftpUrlStr) throws Exception {
        if (null == ftpUrlStr || "".equals(ftpUrlStr.trim())) {
            throw new Exception("ftpstr��Ϊ��");
        }
        ftpUrlStr = ftpUrlStr.replaceAll("\\\\", "/");
        ftpUrlStr = changeUrlCharater(ftpUrlStr);
        String array[] = ftpUrlStr.split("/");
        String[] ftpUserPasswordAndIpPort = array[2].split("@");
        String[] ftpUserAndPassword = ftpUserPasswordAndIpPort[0].split(":");
        String[] ftpIpAndPort = ftpUserPasswordAndIpPort[1].split(":");
        String ftpUser = ftpUserAndPassword[0];
        String ftpPassword = ftpUserAndPassword[1];
        String ftpIp = ftpIpAndPort[0];
        String ftpPort = ftpIpAndPort.length > 1 ? ftpIpAndPort[1] : "";
        String fileName = array[array.length - 1];// ����ļ���
        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put("ftpUser", ftpUser);
        resultMap.put("ftpPassword", ftpPassword);
        resultMap.put("ftpIp", ftpIp);
        resultMap.put("ftpPort", ftpPort);
        resultMap.put("fileName", fileName);
        String path = "";
        for (int i = 3; i < array.length - 1; i++) {
            if (i != array.length - 2) {
                path += array[i] + "/";
            } else {
                path += array[i];
            }
        }
        resultMap.put("path", path);
        return resultMap;
    }

    public static void main(String[] args) {
        String temp = "ftp://vpftp:zn7070@10.10.10.207:21/2018/0101.jpg";
        try {
            boolean flag = deleteFileFromFtpUrl(temp);
            System.out.println(flag);
        } catch (Exception e) {
            System.out.println("ɾ���ļ�ʧ��");
        }
        // String [] strSplit = temp.split("/");
        // for(int i = 0 ; i < strSplit.length ; i++) {
        // System.out.println(i+" = " + strSplit[i]);
        // }
    }

    public static String changeUrlCharater(String tempUrl) {
        tempUrl = tempUrl.replaceAll("%", "%25").replaceAll("#", "%23").replaceAll("\\+", "%2B").replaceAll("&", "%26");
        tempUrl = tempUrl.replaceAll("=", "%3D").replaceAll("\\?", "%3F");
        return tempUrl;
    }

    /**
     * ���ӵ�������
     */
    private static FTPClient connectServer(Ftp ftpUrl) {
        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            ftpClient.setControlEncoding("utf-8");
            if (ftpUrl.getFtpPort() != null) {
                ftpClient.setDefaultPort(ftpUrl.getFtpPort());
            }
            ftpClient.connect(ftpUrl.getFtpIp());
            ftpClient.login(ftpUrl.getFtpUsername(), ftpUrl.getFtpPassword());
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
//			ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
            ftpClient.setBufferSize(10240);
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                System.err.println("FTP server refused connection.");
                log.info("FTP ����ܾ����ӣ�");
            }
        } catch (SocketException e) {
            log.error("��¼ftp������ " + ftpUrl.getFtpIp() + " ʧ��,���ӳ�ʱ��", e);
        } catch (IOException e) {
            log.error("��¼ftp������ " + ftpUrl.getFtpIp() + " ʧ�ܣ�FTP�������޷��򿪣�", e);
        }
        return ftpClient;
    }

    /**
     * �ر�����
     */
    private static void closeConnect(FTPClient ftpClient) {
        try {
            if (ftpClient != null) {
                if (ftpClient.isConnected() == true) {
                    ftpClient.logout();
                }
                ftpClient.disconnect();
            }
        } catch (Exception e) {
            log.error("�ر�ftp����ʧ��", e);
        }
    }

    /**
     * ���뵽��������ĳ��Ŀ¼��
     *
     * @param directory
     */
    private static void changeWorkingDirectory(FTPClient ftpClient, String directory) throws Exception {
        try {
            if(directory.contains("\\")){
                directory = directory.replaceAll("\\\\","/");
            }
            String splitType = "/";
            ftpClient.changeWorkingDirectory(splitType);
            String[] subPathArray = directory.split(splitType);
            for (String subPath : subPathArray) {
                ftpClient.makeDirectory(subPath);
                ftpClient.changeWorkingDirectory(subPath);
            }
        } catch (IOException ioe) {
            log.error("�ı�ftp����·��ʧ��", ioe);
        }
    }

    /**
     * ת��[ISO-8859-1 -> GBK] ��ͬ��ƽ̨��Ҫ��ͬ��ת��
     *
     * @param obj
     * @return ""
     */
    private static String iso8859togbk(Object obj) {
        try {
            if (obj == null) {
                return "";
            }
            return new String(obj.toString().getBytes("iso-8859-1"), "GBK");
        } catch (Exception e) {
            return "";
        }
    }

    public static Ftp getFtpUrlObj(String ftpIp, String ftpPort, String ftpUser, String ftpPassword) {
        Ftp ftpUrl = new Ftp();
        ftpUrl.setFtpIp(ftpIp);
        if (ftpPort != null) {
            ftpUrl.setFtpPort(Integer.parseInt(ftpPort));
        }
        ftpUrl.setFtpUsername(ftpUser);
        ftpUrl.setFtpPassword(ftpPassword);
        return ftpUrl;
    }

}
