package com.common.commonlib.utils

import org.apache.commons.net.ftp.FTP
import org.apache.commons.net.ftp.FTPClient
import org.apache.commons.net.ftp.FTPReply
import java.io.BufferedOutputStream
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException

/**
 * FTP工具类
 *
 * @author wangym
 * @since 2021/7/28
 */
object FTPUtils {
    /**
     * 默认缓冲池大小
     */
    private const val DEFAULT_BUFFER_SIZE = 1024 * 10

    /**
     * 默认编码模式
     */
    private const val DEFAULT_ENCODING = "UTF-8"

    /**
     * 结果
     */
    enum class RESULT { SUCCESS, FAILED }

    /**
     * ftp上传
     * @param url    ftp地址
     * @param port  ftp连接端口号
     * @param username  登录用户名
     * @param password  登录密码
     * @param fileNamePath  本地文件保存路径
     * @param fileName  本地文件名
     * @return
     */
    fun ftpUpload(
        url: String?,
        port: String,
        username: String?,
        password: String?,
        fileNamePath: String,
        fileName: String
    ): RESULT {
        val ftpClient = FTPClient()
        val fis: FileInputStream?
        var returnMessage = RESULT.FAILED
        try {
            ftpClient.connect(url, port.toInt())
            val loginResult = ftpClient.login(username, password)
            val returnCode = ftpClient.replyCode
            if (loginResult && FTPReply.isPositiveCompletion(returnCode)) { // 如果登录成功
                ftpClient.bufferSize = DEFAULT_BUFFER_SIZE
                ftpClient.controlEncoding = DEFAULT_ENCODING
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE)
                ftpClient.enterLocalPassiveMode()
                fis = FileInputStream(fileNamePath + fileName)
                ftpClient.storeFile(fileName, fis)
                returnMessage = RESULT.SUCCESS //上传成功
            } else { // 如果登录失败
                returnMessage = RESULT.FAILED
            }
        } catch (e: IOException) {
            e.printStackTrace()
            returnMessage = RESULT.FAILED
        } finally {
            try {
                ftpClient.disconnect()
            } catch (e: IOException) {
                e.printStackTrace()
                throw RuntimeException("关闭FTP连接发生异常！", e)
            }
        }
        return returnMessage
    }

    /**
     * ftp下载
     * @param url
     * @param port
     * @param username
     * @param password
     * @param filePath 存放文件的路径
     * @param FTP_file 要下载的文件名
     * @param SD_file 本地文件名
     */
    fun ftpDown(
        url: String?,
        port: Int,
        username: String?,
        password: String?,
        filePath: String,
        FTP_file: String?,
        SD_file: String
    ): RESULT {
        val buffOut: BufferedOutputStream?
        val ftpClient = FTPClient()
        var returnMessage = RESULT.FAILED
        try {
            ftpClient.connect(url, port)
            val loginResult = ftpClient.login(username, password)
            val returnCode = ftpClient.replyCode
            if (loginResult && FTPReply.isPositiveCompletion(returnCode)) { // 如果登录成功
                ftpClient.bufferSize = DEFAULT_BUFFER_SIZE
                ftpClient.controlEncoding = DEFAULT_ENCODING
                ftpClient.enterLocalPassiveMode()
                buffOut = BufferedOutputStream(FileOutputStream(filePath + SD_file), 8 * 1024)
                ftpClient.retrieveFile(FTP_file, buffOut)
                buffOut.flush()
                buffOut.close()
                ftpClient.logout()
                ftpClient.disconnect()
                returnMessage = RESULT.SUCCESS //上传成功
            } else { // 如果登录失败
                returnMessage = RESULT.FAILED
            }
        } catch (e: IOException) {
            e.printStackTrace()
            throw java.lang.RuntimeException("FTP客户端出错！", e)
        } finally {
            try {
                ftpClient.disconnect()
            } catch (e: IOException) {
                e.printStackTrace()
                throw java.lang.RuntimeException("关闭FTP连接发生异常！", e)
            }
        }
        return returnMessage
    }
}