package com.yeejoin.amos.boot.module.hygf.api.util;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.yeejoin.amos.boot.module.hygf.api.dto.ResultLinkField;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;


/**
 * 提供SFTP处理文件服务
 *
 * @author
 * @date 2016-02-29
 */

public class SFTPUtil {
    private static final Logger logger = LoggerFactory.getLogger(SFTPUtil.class);
    private JSch jSch = null;
    private ChannelSftp sftp = null;// sftp主服务
    private Channel channel = null;
    private Session session = null;

    private String hostName ;// 远程服务器地址
    private int port = 8001;// 端口
    private String userName ;// 用户名
    private String password ;// 密码
    private String priKeyFile; // 密钥文件
    private String passphrase; // 秘钥字符串


    @Value("${icbc.Withhold.sftpIp:gw.open.icbc.com.cn}")
    public  String sftpIp ="gw.open.icbc.com.cn" ;
    @Value("${icbc.Withhold.sftpPort:8001}")
    public  int sftpPort=8001;
    @Value("${icbc.Withhold.sftpUserName:jrgf}")
    public  String sftpUserName="jrgf";

    public SFTPUtil(String hostName, int port, String userName, String password) {
        this.hostName = hostName;
        this.port = port;
        this.userName = userName;
        this.password = password;
    }


    /**
     * 密钥构造文件
     *
     * @param hostName
     * @param port
     * @param userName
     * @param priKeyFile
     * @param passphrase
     */

    public SFTPUtil(String hostName, int port, String userName,
                    String priKeyFile, String passphrase) {
        this.hostName = hostName;
        this.port = port;
        this.userName = userName;
        this.password = null;
        this.priKeyFile = priKeyFile;
        this.passphrase = passphrase;
    }


    /**
     * 连接登陆远程服务器
     *
     * @return
     * @throws Exception
     */

    public boolean connect() throws Exception {
        try {
            jSch = new JSch();
            session = jSch.getSession(userName, hostName, port);
            session.setPassword(password);

            session.setConfig(this.getSshConfig());
            session.connect();

            channel = session.openChannel("sftp");
            channel.connect();

            sftp = (ChannelSftp) channel;
            logger.info("登陆成功:" + sftp.getServerVersion());

        } catch (JSchException e) {
            logger.error("SSH方式连接FTP服务器时有JSchException异常!");
            logger.error(e.getMessage());
            throw e;
        }
        return true;
    }


    /**
     * 密钥文件连接
     *
     * @return
     */
    public boolean priKeyConnect() throws Exception {
        JSch jsch = new JSch();
        try {
            if (priKeyFile != null && !"".equals(priKeyFile)) {


                // 通过类加载器获取私钥文件输入流
                InputStream inputStream = getClass().getClassLoader().getResourceAsStream(priKeyFile);
                if (inputStream == null) {
                    throw new IOException("Private key file not found in classpath: " + priKeyFile);
                }

                // 创建临时文件并写入私钥内容
                File tempPrivateKeyFile = File.createTempFile("temp_private_key", ".pem");
                try (FileOutputStream fos = new FileOutputStream(tempPrivateKeyFile)) {
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        fos.write(buffer, 0, bytesRead);
                    }
                } finally {
                    inputStream.close();
                }

                // 设置私钥文件权限（仅适用于 Unix/Linux 系统）
                tempPrivateKeyFile.setReadable(true, false);
                if (passphrase != null && !"".equals(passphrase)) {
                    jsch.addIdentity(tempPrivateKeyFile.getAbsolutePath(), passphrase);
                } else {
                    jsch.addIdentity(tempPrivateKeyFile.getAbsolutePath());
                }
            }
            if (port > 0) {
                session = jsch.getSession(userName, hostName, port);
            } else {
                session = jsch.getSession(userName, hostName);
            }
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            // session.setTimeout(20000);
            session.connect(3000);
            channel = session.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
        } catch (JSchException e) {
            logger.error("SSH方式连接FTP服务器时有JSchException异常!");
            logger.error(e.getMessage());
            throw e;
        }
        return true;
    }


    /**
     * 关闭连接
     *
     * @throws Exception
     */

    private void disconnect() throws Exception {
        try {
            if (sftp.isConnected()) {
                sftp.disconnect();
            }
            if (channel.isConnected()) {
                channel.disconnect();
            }
            if (session.isConnected()) {
                session.disconnect();
            }
        } catch (Exception e) {
            throw e;
        }
    }


    /**
     * 获取服务配置
     *
     * @return
     */

    private Properties getSshConfig() throws Exception {
        Properties sshConfig = null;
        try {
            sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");

        } catch (Exception e) {
            throw e;
        }
        return sshConfig;
    }


    /**
     * 下载远程sftp服务器文件
     *
     * @param remotePath
     * @param remoteFilename
     * @param localFilename
     * @return
     */

    public  boolean downloadFile(String remotePath, String remoteFilename,
                                String localFilename) throws SftpException, IOException, Exception {
        FileOutputStream output = null;
        boolean success = false;
        try {
            if (null != remotePath && remotePath.trim() != "") {
                sftp.cd(remotePath);
            }

            File localFile = new File(localFilename);
            // 有文件和下载文件重名
            if (localFile.exists()) {
                logger.error("文件: " + localFilename + " 已经存在!");
                return success;
            }
            output = new FileOutputStream(localFile);
            sftp.get(remoteFilename, output);
            success = true;
            logger.info("成功接收文件,本地路径：" + localFilename);
        } catch (SftpException e) {
            logger.error("接收文件时有SftpException异常!");
            logger.error(e.getMessage());
            return success;
        } catch (IOException e) {
            logger.error("接收文件时有I/O异常!");
            logger.error(e.getMessage());
            return success;
        } finally {
            try {
                if (null != output) {
                    output.close();
                }
            } catch (IOException e) {
                logger.error("关闭文件时出错!");
                logger.error(e.getMessage());
            }
        }
        return success;
    }

    /**
     * 下载远程SFTP服务器中包含特定名称的所有文件并打包到一个ZIP压缩包中
     *
     * @param remotePath      远程目录路径
     * @param filenamePattern 文件名模式（例如，"xxx"）
     * @param localZipPath    本地ZIP文件保存路径
     * @return 是否成功
     */
  //  public  boolean downloadAndZipFiles(String remotePath, String filenamePattern, String localZipPath) {
//        boolean success = false;
//        Path tempDir = null;
//        try {
//            // 创建临时目录
//            tempDir = Files.createTempDirectory("sftp_download_temp");
//
//            // 列出远程目录中的所有文件`
//            Vector<?> filesList = sftp.ls(remotePath);
//
//            List<Path> downloadedFiles = new ArrayList<>();
//            for (Object obj : filesList) {
//                ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) obj;
//                String filename = entry.getFilename();
//                if (filename.contains(filenamePattern)) {
//                    Path localFilePath = tempDir.resolve(filename);
//                    downloadFile(remotePath, filename, localFilePath.toString());
//                    downloadedFiles.add(localFilePath);
//                }
//            }
//
//            // 打包下载的文件到ZIP文件
//           FileUtils.createZipFile(downloadedFiles, localZipPath);
//            success = true;
//            logger.info("成功接收文件并打包到ZIP文件: " + localZipPath);
//        } catch (Exception e) {
//            logger.error("下载或打包文件时发生异常!", e);
//        } finally {
//            try {
//                // 删除临时目录及其内容
//                if (tempDir != null) {
//                    FileUtils.cleanup(tempDir);
//                }
//                disconnect();
//            } catch (IOException e) {
//                logger.error("删除临时目录时出错!", e);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//        return success;
//    }

    public boolean downloadAndZipFiles(String remotePath, String filenamePattern, String localZipPath,Boolean flag) {
        boolean success = false;
        Path tempDir = null;
        try {
            // 创建临时目录
            tempDir = Files.createTempDirectory("sftp_download_temp");

            // 列出远程目录中的所有文件
            Vector<?> filesList = sftp.ls(remotePath);

            List<Path> downloadedFiles = new ArrayList<>();
            for (Object obj : filesList) {
                ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) obj;
                String filename = entry.getFilename();
                if (filename.contains(filenamePattern)) {
                    Path localFilePath = tempDir.resolve(filename);
                    downloadFile(remotePath, filename, localFilePath.toString());
                    downloadedFiles.add(localFilePath);
                }
            }
            if (flag){
                disconnect();
            }

            // 确保本地ZIP路径的父目录存在
            Path localZipFilePath = Paths.get(localZipPath);
            Path parentDir = localZipFilePath.getParent();
            if (parentDir != null && !Files.exists(parentDir)) {
                Files.createDirectories(parentDir);
            }

            // 打包下载的文件到ZIP文件
            FileUtils.createZipFile(downloadedFiles, localZipPath);
            success = true;
            logger.info("成功接收文件并打包到ZIP文件: " + localZipPath);
        } catch (SftpException e) {
            logger.error("下载文件时发生异常!", e);
        } catch (IOException e) {
            logger.error("处理文件或创建目录时发生异常!", e);
        } catch (Exception e) {
            logger.error("其他异常!", e);
        } finally {
            try {
                // 删除临时目录及其内容
                if (tempDir != null) {
                    FileUtils.cleanup(tempDir);
                }
                disconnect();
            } catch (IOException e) {
                logger.error("删除临时目录时出错!", e);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return success;
    }
    /**
     * 上传文件至远程sftp服务器
     *
     * @param remotePath
     * @param remoteFilename
     * @param localFileName
     * @return
     */

    public boolean uploadFile(String remotePath, String remoteFilename,
                              String localFileName) throws SftpException, Exception {
        boolean success = false;
        FileInputStream fis = null;
        try {
            // 更改服务器目录
            if (null != remotePath && remotePath.trim() != "") {
                sftp.cd(remotePath);
            }
            File localFile = new File(localFileName);
            fis = new FileInputStream(localFile);
            // 发送文件
            sftp.put(fis, remoteFilename);
            success = true;
            logger.info("成功发送文件,本地路径：" + localFileName);
        } catch (SftpException e) {
            logger.error("发送文件时有SftpException异常!");
            e.printStackTrace();
            logger.error(e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("发送文件时有异常!");
            logger.error(e.getMessage());
            throw e;
        } finally {
            try {
                if (null != fis) {
                    fis.close();
                }
//                // 关闭连接
//                disconnect();
            } catch (IOException e) {
                logger.error("关闭文件时出错!");
                logger.error(e.getMessage());
            }
        }
        return success;
    }

    /**
     * 上传文件至远程sftp服务器
     *
     * @param remotePath
     * @param remoteFilename
     * @param input
     * @return
     */

    public boolean uploadFile(String remotePath, String remoteFilename,
                              InputStream input) throws SftpException, Exception {
        boolean success = false;
        try {
            // 更改服务器目录
            if (null != remotePath && remotePath.trim() != "") {
                sftp.cd(remotePath);
            }

            // 发送文件
            sftp.put(input, remoteFilename);
            success = true;
        } catch (SftpException e) {
            logger.error("发送文件时有SftpException异常!");
            e.printStackTrace();
            logger.error(e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("发送文件时有异常!");
            logger.error(e.getMessage());
            throw e;
        } finally {
            try {
                if (null != input) {
                    input.close();
                }
                // 关闭连接
                disconnect();
            } catch (IOException e) {
                logger.error("关闭文件时出错!");
                logger.error(e.getMessage());
            }

        }
        return success;
    }

    /**
     * 删除远程文件
     *
     * @param remotePath
     * @param remoteFilename
     * @return
     * @throws Exception
     */

    public boolean deleteFile(String remotePath, String remoteFilename)
            throws Exception {
        boolean success = false;
        try {
            // 更改服务器目录
            if (null != remotePath && remotePath.trim() != "") {
                sftp.cd(remotePath);
            }

            // 删除文件
            sftp.rm(remoteFilename);
            logger.error("删除远程文件" + remoteFilename + "成功!");
            success = true;
        } catch (SftpException e) {
            logger.error("删除文件时有SftpException异常!");
            e.printStackTrace();
            logger.error(e.getMessage());
            return success;
        } catch (Exception e) {
            logger.error("删除文件时有异常!");
            logger.error(e.getMessage());
            return success;
        } finally {
            // 关闭连接
            disconnect();
        }
        return success;
    }

    /**
     * 遍历远程文件
     *
     * @param remotePath
     * @return
     * @throws Exception
     */

    public List<String> listFiles(String remotePath) throws SftpException {
        List<String> ftpFileNameList = new ArrayList<String>();
        Vector<LsEntry> sftpFile = sftp.ls(remotePath);
        LsEntry isEntity = null;
        String fileName = null;
        Iterator<LsEntry> sftpFileNames = sftpFile.iterator();
        while (sftpFileNames.hasNext()) {
            isEntity = (LsEntry) sftpFileNames.next();
            fileName = isEntity.getFilename();
            logger.info(fileName);
            ftpFileNameList.add(fileName);
        }
        return ftpFileNameList;
    }


    /**
     * 判断路径是否存在
     *
     * @param remotePath
     * @return
     * @throws SftpException
     */

    public boolean isExist(String remotePath) throws SftpException {
        boolean flag = false;
        try {
            sftp.cd(remotePath);
            logger.info("存在路径：" + remotePath);
            flag = true;
        } catch (SftpException sException) {

        } catch (Exception Exception) {
        }
        return flag;
    }

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPriKeyFile() {
        return priKeyFile;
    }

    public void setPriKeyFile(String priKeyFile) {
        this.priKeyFile = priKeyFile;
    }

    public String getPassphrase() {
        return passphrase;
    }

    public void setPassphrase(String passphrase) {
        this.passphrase = passphrase;
    }





    public boolean uploadAndUnzip(String remotePath, String remoteZipFilename, String localZipFilePath) throws Exception {
        boolean success = false;
        FileInputStream fis = null;
        try {
            // 上传 ZIP 文件
            if (uploadFile(remotePath, remoteZipFilename, localZipFilePath)) {
                // 解压 ZIP 文件
                unzipFile(remotePath, remoteZipFilename);
                success = true;
            }
        }catch (Exception e) {
            logger.error("异常信息：" + e.getMessage());
        }finally {
            IOUtils.closeQuietly(fis);
            disconnect();
        }
        return success;
    }





    private void unzipFile(String remotePath, String remoteZipFilename) throws Exception {
        // 打印当前 SFTP 工作目录
        try {
            System.out.println("Current SFTP working directory: " + sftp.pwd());
        } catch (SftpException e) {
            System.err.println("Failed to get current SFTP working directory.");
            throw e;
        }

        // 切换到指定的远程路径（如果提供了有效路径）
        if (StringUtils.isNotBlank(remotePath) && !sftp.pwd().equals(remotePath)) {
            try {
                sftp.cd(remotePath);
                System.out.println("Changed to remote directory: " + remotePath);
            } catch (SftpException e) {
                System.err.println("Failed to change to remote directory: " + remotePath);
                throw e;
            }
        }

        if (!sftp.isConnected()) {
            reconnect();
        }

        // 获取 ZIP 文件的输入流
        try (InputStream zipIn = sftp.get(remoteZipFilename);ZipInputStream zin = new ZipInputStream(zipIn)) {
            ZipEntry entry;
            while ((entry = zin.getNextEntry()) != null) {
                // 假设 ZIP 中只包含文件条目，直接处理文件
                System.out.println(sftp.pwd());
                String remoteFilePath = remotePath + "/" + entry.getName();
                System.out.println(sftp.pwd());
                logger.info("Processing file: {}", remoteFilePath);
                // 将 ZIP 条目内容写入远程文件
                try (OutputStream out = sftp.put(remoteFilePath)) {
                    IOUtils.copy(zin, out);
                } catch (SftpException e) {
                    logger.error("Failed to upload file: {}. Error: {}", remoteFilePath, e.getMessage(), e);
                    throw e;
                }
                // 关闭当前 ZIP 条目
                zin.closeEntry();
            }
        } catch (Exception e){
            logger.error("异常信息：" + e.getMessage());
        }

        // 删除已解压的 ZIP 文件
        try {
            sftp.rm(remoteZipFilename);
            disconnect();
            System.out.println("Removed ZIP file: " + remoteZipFilename);
        } catch (SftpException e) {
            System.err.println("Failed to remove ZIP file: " + remoteZipFilename);
            throw e;
        }
    }


//    private void unzipFile(String remotePath, String remoteZipFilename) throws SftpException, IOException {
////        if (StringUtils.isNotBlank(remotePath)) {
////            sftp.cd(remotePath);
////        }
//
//        // 获取 ZIP 文件
//        System.out.println(sftp.pwd());
//        InputStream zipIn = sftp.get(remoteZipFilename);
//        ZipInputStream zin = new ZipInputStream(zipIn);
//        ZipEntry entry;
//        while ((entry = zin.getNextEntry()) != null) {
//            if (entry.isDirectory()) {
//                createDirectory(remotePath, entry.getName());
//            } else {
//                // 创建文件
//                File file = new File(entry.getName());
//                String filePath = remotePath + "/" + file.getParent();
//                if (file.getParent() != null && !filePath.equals(remotePath)) {
//                    createDirectory(filePath, "");
//                }
//                OutputStream out = sftp.put(entry.getName());
//                IOUtils.copy(zin, out);
//                out.close();
//            }
//            zin.closeEntry();
//        }
//        zin.close();
//        zipIn.close();
//
//        // 删除 ZIP 文件
//        sftp.rm(remoteZipFilename);
//    }
//

    private void createDirectory(String remotePath, String dirName) throws SftpException {
        if (StringUtils.isNotBlank(dirName)) {
            String[] dirs = dirName.split("/");
            for (String dir : dirs) {
                if (dir.trim().length() > 0) {
                    remotePath += "/" + dir;
                    try {
                        sftp.lstat(remotePath);
                    } catch (SftpException e) {
                        if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
                            sftp.mkdir(remotePath);
                        } else {
                            throw e;
                        }
                    }
                }
            }
        }
    }



    public static void testSFTP1() {
        try {
            SFTPUtil sftp = new SFTPUtil("106.120.68.125", 8001,
                    "huidan",
                    "C:\\Users\\Administrator\\Desktop\\爱养牛\\id_rsa", null);
            logger.info(String.valueOf(new StringBuffer().append("服务器地址: ")
                    .append(sftp.getHostName()).append(" 端口：")
                    .append(sftp.getPort()).append("用户名：")
                    .append(sftp.getUserName()).append("密钥文件:")
                    .append(sftp.getPriKeyFile())));
            sftp.priKeyConnect();

            // 服务器文件存放路径
            String path = "/";

            if (sftp.isExist(path)) {
                sftp.uploadAndUnzip(path, "testupload.zip", "C:\\Users\\Administrator\\Desktop\\爱养牛\\testFile.zip");
                logger.info("上传并解压成功");
            }

        } catch (Exception e) {
            logger.error("异常信息：" + e.getMessage());
        }
    }

    /**
     * 尝试重新连接到 SFTP 服务器。
     */
    private void reconnect() throws Exception {

        SFTPUtil sftp1 = new SFTPUtil(sftpIp, sftpPort,
                sftpUserName,
                "secretKey/登录-gxjrid_rsa", null);
        logger.info(String.valueOf(new StringBuffer().append("服务器地址: ")
                .append(sftp1.getHostName()).append(" 端口：")
                .append(sftp1.getPort()).append("用户名：")
                .append(sftp1.getUserName()).append("密钥文件:")
                .append(sftp1.getPriKeyFile())));
        sftp1.priKeyConnect();

//        if (session != null && !session.isConnected()) {
//            session.connect();
//        }
//        if (sftp != null && !sftp.isConnected()) {
//            ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
//            channel.connect();
//            this.sftp = channel;
//        }
    }




    /**
     * 先解压本地 ZIP 文件，然后上传解压后的文件到远程服务器。
     *
     * @param remotePath       远程服务器上的目标目录路径。
     * @param localZipFilePath  本地 ZIP 文件的完整路径。
     * @return 操作是否成功。
     * @throws Exception 如果操作失败。
     */
    public boolean unzipAndUpload(String remotePath, String localZipFilePath) throws Exception {
        boolean success = false;
        File tempDir = null;

        try {
            // 创建临时目录用于解压
            tempDir = Files.createTempDirectory("unzip_temp_").toFile();
            tempDir.deleteOnExit(); // 确保 JVM 退出时删除临时目录

            // 解压本地 ZIP 文件到临时目录
            unzipLocalFile(localZipFilePath, tempDir.getAbsolutePath());

            // 获取解压后的文件列表
            File[] files = tempDir.listFiles();
            if (files == null || files.length == 0) {
                throw new IOException("No files found after unzipping.");
            }

            // 上传解压后的文件到远程服务器
            for (File file : files) {
                uploadFile(remotePath, file.getName(), file.getAbsolutePath());
            }

            success = true;
        } catch (Exception e) {
            logger.error("异常信息：" + e.getMessage(), e);
            throw e;
        } finally {
            // 清理临时文件和断开连接
            if (tempDir != null) {
                FileUtils.cleanup(tempDir.toPath());
            }
            disconnect();
        }

        return success;
    }

    /**
     * 解压本地 ZIP 文件到指定目录。
     *
     * @param zipFilePath 本地 ZIP 文件的完整路径。
     * @param destDir     目标解压目录。
     * @throws IOException 如果解压过程中发生错误。
     */
    private void unzipLocalFile(String zipFilePath, String destDir) throws IOException {
        byte[] buffer = new byte[1024];
        Path zipFilePathObj = Paths.get(zipFilePath);
        Path destDirObj = Paths.get(destDir);

        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePathObj.toFile()))) {
            ZipEntry zipEntry = zis.getNextEntry();

            while (zipEntry != null) {
                Path newFilePath = destDirObj.resolve(zipEntry.getName());

                if (!zipEntry.isDirectory()) {
                    // 如果是文件，则创建新文件并写入内容
                    Files.createDirectories(newFilePath.getParent());
                    try (FileOutputStream fos = new FileOutputStream(newFilePath.toFile())) {
                        int len;
                        while ((len = zis.read(buffer)) > 0) {
                            fos.write(buffer, 0, len);
                        }
                    }
                } else {
                    // 如果是目录，则创建目录
                    Files.createDirectories(newFilePath);
                }

                zipEntry = zis.getNextEntry();
            }
            zis.closeEntry();
        }
    }


    /**
     * 获取指定目录下所有 .failure 文件的内容并解析为 JSON 对象。
     *
     * @param remotePath 远程服务器上的目标目录路径。
     * @return 解析后的 JSON 对象列表。
     * @throws Exception 如果操作失败。
     */
    public List<Map<String, Object>> getAllFailureFilesContentAsJson(String remotePath) throws Exception {
        List<Map<String, Object>> allJsonData = new ArrayList<>();
        try {
            // 列出远程目录下的所有文件
            @SuppressWarnings("unchecked")
            List<ChannelSftp.LsEntry> fileList = (List<ChannelSftp.LsEntry>) sftp.ls(remotePath + "/*.failure");

            for (ChannelSftp.LsEntry entry : fileList) {
                String fileName = entry.getFilename();
                if (!fileName.equals(".") && !fileName.equals("..")) { // 排除当前和上级目录条目
                    Map<String, Object> jsonData = getFailureFileContentAsJson(remotePath, fileName);
                    allJsonData.add(jsonData);
                }
            }
        } catch (SftpException e) {
            logger.error("Failed to list files in directory: {}. Error: {}", remotePath, e.getMessage(), e);
            throw e;
        }
        return allJsonData;
    }


    /**
     * 获取指定目录下所有  结果文件的内容并解析为 JSON 对象。
     *
     * @param remotePath 远程服务器上的目标目录路径。
     * @return 解析后的 JSON 对象列表。
     * @throws Exception 如果操作失败。
     */
    public List<ResultLinkField> getAllResultFilesContentAsJson(String remotePath) throws Exception {
        List<ResultLinkField> allJsonData = new ArrayList<>();
        try {
            // 列出远程目录下的所有文件
            @SuppressWarnings("unchecked")
            List<ChannelSftp.LsEntry> fileList = (List<ChannelSftp.LsEntry>) sftp.ls(remotePath + "/ENTRUSTRESULT-*.bin");

            for (ChannelSftp.LsEntry entry : fileList) {
                String fileName = entry.getFilename();
                if (!fileName.equals(".") && !fileName.equals("..")) { // 排除当前和上级目录条目
                    String fileContentAsString = getFileContentAsString(remotePath, fileName);
                    List<String> contents = Arrays.asList(fileContentAsString.split("\r\n"));
                    if (null != contents && contents.size() > 0) {
                        for (String content : contents) {
                            ResultLinkField resultLinkField = contentHandle(content);
                            allJsonData.add(resultLinkField);
                        }
                    }
                }
            }
        } catch (SftpException e) {
            logger.error("Failed to list files in directory: {}. Error: {}", remotePath, e.getMessage(), e);
            throw e;
        }
        return allJsonData;
    }

    ResultLinkField contentHandle(String content){
        ResultLinkField resultLinkField = new ResultLinkField();
        resultLinkField.setZoneNo(content.substring(0,5));
        resultLinkField.setBatchNo(content.substring(5,23));
        resultLinkField.setBillNo(content.substring(23,53).replace(" ",""));
        resultLinkField.setStatus(content.substring(53,54));
        resultLinkField.setErrMsg(content.substring(54,content.length()-37).replace(" ",""));
        resultLinkField.setTimestamp(content.substring(content.length()-37,content.length()-17));
        resultLinkField.setAmt(content.substring(content.length()-17,content.length()).replace(" ",""));
        return resultLinkField;
    }

    /**
     * 读取指定文件的内容并转换为字符串。
     *
     * @param remotePath 远程服务器上的目标目录路径。
     * @param fileName   文件名。
     * @return 文件内容的字符串表示。
     * @throws Exception 如果操作失败。
     */
    private String getFileContentAsString(String remotePath, String fileName) throws Exception {
        StringBuilder contentBuilder = new StringBuilder();
        InputStream inputStream = null;
        try {
            inputStream = sftp.get(remotePath + "/" + fileName);
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                contentBuilder.append(new String(buffer, 0, bytesRead, Charset.forName("GB2312")));
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return contentBuilder.toString();
    }



    /**
     * 获取指定目录下所有 .failure 文件的内容并解析为 JSON 对象。
     *
     * @param remotePath 远程服务器上的目标目录路径。
     * @return 解析后的 JSON 对象列表。
     * @throws Exception 如果操作失败。
     */
    public List<String> getAllSuccessFilesContentAsJson(String remotePath) throws Exception {
        List<String> batchNos = new ArrayList<>();
        try {
            // 列出远程目录下的所有文件
            @SuppressWarnings("unchecked")
            List<ChannelSftp.LsEntry> fileList = (List<ChannelSftp.LsEntry>) sftp.ls(remotePath + "/*.success");

            for (ChannelSftp.LsEntry entry : fileList) {
                String fileName = entry.getFilename();
                if (!fileName.equals(".") && !fileName.equals("..")) { // 排除当前和上级目录条目
                    batchNos.add(fileName.substring(fileName.length()-18-8).replace(".success",""));
                }
            }
        } catch (SftpException e) {
            logger.error("Failed to list files in directory: {}. Error: {}", remotePath, e.getMessage(), e);
            throw e;
        }
        return batchNos;
    }

    /**
     * 从 SFTP 服务器获取 .failure 文件内容并解析为 JSON 对象。
     *
     * @param remotePath       远程服务器上的目标目录路径。
     * @param remoteFilename   远程文件名（包括扩展名）。
     * @return 解析后的 JSON 对象。
     * @throws Exception 如果操作失败。
     */
    private Map<String, Object> getFailureFileContentAsJson(String remotePath, String remoteFilename) throws Exception {
        try (InputStream inputStream = getRemoteFileInputStream(remotePath, remoteFilename)) {
            // 使用 Jackson 解析 JSON 内容
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.readValue(inputStream, Map.class);
        } catch (SftpException | IOException e) {
            logger.error("Failed to retrieve and parse file content: {}. Error: {}", remoteFilename, e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 获取远程文件的输入流。
     *
     * @param remotePath       远程服务器上的目标目录路径。
     * @param remoteFilename   远程文件名（包括扩展名）。
     * @return 文件的输入流。
     * @throws Exception 如果操作失败。
     */
    private InputStream getRemoteFileInputStream(String remotePath, String remoteFilename) throws Exception {
        if (!sftp.isConnected()) {
            reconnect();
        }
        // 打印尝试获取的文件路径
        logger.info("Attempting to retrieve file: {}/{}", remotePath, remoteFilename);

        try {
            // 检查文件是否存在
            if (!fileExists(remotePath + "/" + remoteFilename)) {
                throw new FileNotFoundException("File not found: " + remoteFilename);
            }

            // 获取文件的输入流
            return sftp.get(remotePath + "/" + remoteFilename);
        } catch (SftpException e) {
            logger.error("Failed to access file at path: {}/{}. Error: {}", remotePath, remoteFilename, e.getMessage(), e);
            throw e;
        }
    }


    /**
     * 检查远程文件是否存在。
     */
    private boolean fileExists(String remoteFilePath) throws SftpException {
        try {
            sftp.stat(remoteFilePath);
            return true;
        } catch (SftpException e) {
            if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
                return false;
            }
            throw e; // 对于其他错误，重新抛出异常
        }
    }
}

