package com.steering.comm.file;

import CoreFS.SA08.CoreFileStorageImpl;

import com.steering.comm.tools.StringTool;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.log4j.Logger;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * FTP客户端扩展
 * @author siy 2015-03-12
 * @version v1.0
 */
public class CoreFTPClient extends FTPClient {
    private static CoreFTPClient instance = null;

    public Logger logger = Logger.getLogger(CoreFTPClient.class);

    private String ip = null;
    // private int port = 21;
    private String userName = null;
    private String password = null;
    private String encoding = "UTF-8";

    public String getEncoding() {
        return encoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    private CoreFTPClient() {

    }

    /**
     * 获取CoreFTPClient实例
     * @return
     */
    public synchronized static CoreFTPClient newInstance() {
        if (instance == null) {
            instance = new CoreFTPClient();
        }
        return instance;
    }

    /**
     * 从配置文件获取FtpServer连接信息
     */
    private void loadPro() {
        Properties pro = new Properties();
        try {
            pro.load(CoreFileStorageImpl.class
                    .getResourceAsStream("/imagePath.properties"));
            ip = pro.getProperty("IP");
            userName = pro.getProperty("UserName");
            password = pro.getProperty("PWD");
            String str = pro.getProperty("maxBackupIndex");
            String str1 = pro.getProperty("gapTime");
            // maxBackupIndex = Integer.parseInt(str);
            // gapTime = Long.parseLong(str1);
        }
        catch (IOException e) {
            logger.error(e);
        }
    }

    /**
     * 创建FTP目录
     * @param path 路径
     * @return 是否成功
     * @throws IOException
     */
    public boolean createDir(String path) throws IOException {
        if (StringTool.isNullOrEmpty(path)) {
            return false;
        }
        if (path.startsWith("/")) {
            path = path.substring(1, path.length());
        }
        String[] paths = path.split("/");
        String workPath = "/ftp/ftpuser";
        for (int i = 0; i < paths.length; i++) {
            workPath = workPath + "/" + paths[i];
            if (!this.changeWorkingDirectory(workPath)) {  //进不去目录，说明该目录不存在
                if (!this.makeDirectory(workPath)) { //创建目录
                    //如果创建文件目录失败，则返回
                    System.out.println("创建文件目录"+workPath+"失败");
                } else {
                    //目录存在，则直接进入该目录
                	this.changeWorkingDirectory(workPath);
                }
            }
        }
        return true;
    }

    /**
     * 判断路径是目录还是文件
     * @param path 路径名称
     * @return
     */
    public boolean isPath(String path) {
        boolean flag = true;
        try {
            flag = this.changeWorkingDirectory(path); // 不是目录时，将报错
            this.changeWorkingDirectory("/"); // 回到根目录
        }
        catch (Exception e) {
            flag = false;
        }
        
        return flag;
    }

    /**
     * 删除目录及目录中的文件
     * @param pathname 目录路径
     * @return 是否删除成功
     */
    public boolean deletePath(String pathname) {
        try {
            FTPFile[] files = this.listFiles(pathname);
            for (FTPFile f : files) {
                if (f.isDirectory()) {
                    this.deletePath(pathname + "/" + f.getName());
                    this.removeDirectory(pathname);
                }
                if (f.isFile()) {
                    this.deleteFile(pathname + "/" + f.getName());
                }
            }
            if(this.isPath(pathname)){
                this.removeDirectory(pathname);
            }
        }
        catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 连接FTP服务
     * @return 是否连接成功
     * @throws Exception
     */
    public boolean open() throws Exception {
        boolean connected = true;
        try {
            if (StringTool.isNullOrEmpty(ip)) {
                loadPro();
            }
            this.connect(ip);
            connected = this.login(userName, password);
            encoding = this.getControlEncoding();
            this.setControlEncoding("GBK");
            this.setBufferSize(1024);
            // 设置文件类型（二进制）
            this.setFileType(FTP.BINARY_FILE_TYPE);
        }
        catch (Exception e) {
            // TODO Auto-generated catch block
            throw (e);
        }

        return connected;
    }

    /**
     * 关闭FTP连接
     * @return 是否关闭成功
     * @throws Exception
     */
    public boolean close() throws Exception {
        boolean closed = true;
        try {
            if (this.isConnected()) {
                this.logout();
                this.disconnect();
            }
        }
        catch (Exception e) {
            // TODO Auto-generated catch block
            throw (e);
        }

        return closed;
    }

    /**
     * 上传文件
     * @param b 文件byte数组
     * @param name 文件名
     * @param path 文件保存路径
     * @throws Exception
     */
    public void upload(byte[] b, String name, String path) throws Exception {
        try {
            ByteArrayInputStream stream = new ByteArrayInputStream(b);

            // 设置上传目录
            boolean changed = this.changeWorkingDirectory(path);
            if (!changed) {
                createDir(path);
            }
            boolean result = this.storeFile(new String(name.getBytes("UTF-8")), stream);
            if (result) {
                System.out.println("上传成功!");
            }
            stream.close();
            this.changeWorkingDirectory("/");
        }
        catch (Exception e) {
            throw (e);
        }
    }

    /**
     * 下载文件
     * @param fileName 文件全名
     * @return 文件byte数组
     * @throws Exception
     */
    public byte[] Download(String fileName) throws Exception {
        InputStream is = null;
        byte[] bytes = null;
        try {
            is = this.retrieveFileStream(fileName);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int count =0;
            while((count = is.read(buffer)) > 0){
                out.write(buffer,0,count);
            }
                
            bytes = out.toByteArray();//CoreUtil.toByteArray(is);
            out.close();
            is.close();
            this.completePendingCommand();
        }
        catch (Exception e) {
            throw (e);
        }
        return bytes;
    }
}
