package com.dxhy.oss.service;

import cn.hutool.core.io.FileUtil;
import com.dxhy.oss.utils.SshPool;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;

/**
 * @author jiaohongyang
 */
@Slf4j
public class SshService {

    private final SshPool pool;

    public SshService(SshPool pool) {
        this.pool = pool;
    }

    /**
     * 将输入流的数据上传到sftp作为文件。文件完整路径 = basePath+directory
     *
     * @param pathName       ftp服务保存地址，完整路径
     * @param fileName       上传到ftp的文件名
     * @param originFileName 待上传文件的名称（绝对地址）
     */

    public boolean uploadFile(String pathName, String fileName, String originFileName)  {
        log.info("开始上传文件");
        ChannelSftp sftp = null;
        InputStream inputStream;
        try {
            sftp = pool.borrowObject();
            try {
                sftp.cd(pathName);
            } catch (SftpException e) {
                // 目录不存在，则创建文件夹
                String[] dirs = pathName.split("/");
                String tempPath = "";
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir)) {
                        continue;
                    }
                    tempPath += "/" + dir;
                    try {
                        sftp.cd(tempPath);
                    } catch (SftpException ex) {
                        try {
                            sftp.mkdir(tempPath);
                            sftp.cd(tempPath);
                        } catch (SftpException e1) {
                            e1.printStackTrace();
                        }
                    }
                }
            }

            File orgFile = new File(originFileName);
            inputStream = Files.newInputStream(orgFile.toPath());
            sftp.put(inputStream, fileName);
            inputStream.close();
            // 删除本地文件，防止服务器空间不足
            FileUtil.del(orgFile);
            log.info("上传文件成功");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("上传文件失败");
            return false;
        } finally {
            if (sftp != null) {
                log.info("回收线程");
                pool.returnObject(sftp);
            }

        }
    }


    public boolean downloadFile(String directory, String downloadFile, String saveFile) {
        log.info("开始下载文件!");
        ChannelSftp sftp = null;
        try {
            sftp = pool.borrowObject();
            if (directory != null && !"".equals(directory)) {
                sftp.cd(directory);
            }
            String file = saveFile + "/" + downloadFile;
            File fileLocal = new File(file);
            if (fileLocal.exists()) {
                boolean delete = fileLocal.delete();
                log.info("删除本地路径文件：{}", delete);
            }
            this.directoryIsExists(saveFile);
            sftp.get(downloadFile, file);
            log.info("下载文件成功!");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.info("下载文件失败!");
            return false;
        } finally {
            if (sftp != null) {
                log.info("回收线程");
                pool.returnObject(sftp);
            }

        }


    }


    /**
     * 删除文件
     *
     * @param directory  要删除文件所在目录
     * @param deleteFile 要删除的文件
     * @return 返回是否删除成功
     */

    public boolean deleteFile(String directory, String deleteFile) {
        ChannelSftp sftp = null;
        try {
            sftp = pool.borrowObject();
            sftp.cd(directory);
            sftp.rm(deleteFile);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (sftp != null) {
                log.info("回收线程");
                pool.returnObject(sftp);
            }
        }
    }


    public void directoryIsExists(String path) {
        File directory = new File(path);
        if (directory.exists()) {
            return;
        }

        if (!directory.mkdir()) {
            return;
        }

        if (directory.canWrite()) {
            return;
        }

        boolean setWritable = directory.setWritable(true);
        log.info("是否创建文件  directoryIsExists ：{} ", setWritable);

    }
}
