package com.jiayue.ipp.idp.service.an;


import cn.hutool.core.lang.Filter;
import cn.hutool.extra.ftp.Ftp;
import cn.hutool.extra.ftp.FtpConfig;
import cn.hutool.extra.ftp.FtpMode;
import com.jiayue.ipp.common.data.entity.an.ParsingChannel;
import com.jiayue.ipp.common.data.entity.an.ParsingLog;
import com.jiayue.ipp.common.data.entity.an.ParsingUrl;
import com.jiayue.ipp.idp.dto.ParsingConstant;
import com.jiayue.ipp.idp.util.FileUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ftp通信业务层
 *
 * @author tl
 * @date 2022-05-11 09:51:21
 */
@RequiredArgsConstructor
@Slf4j
@Service
@Transactional
public class FTPService {

    private final ParsingChannelService parsingChannelService;

    private final ParsingUrlService parsingUrlService;

//    private final MinioUtilService minioUtilService;

    private final ParsingFileService parsingFileService;

//    private final DaMinioFileMapper daMinioFileMapper;

    private final ParsingLogService parsingLogService;

    private final String bucketName = "ipp-da";

    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");

    private final SimpleDateFormat simpleDateTimeFormat = new SimpleDateFormat("yyyy-MM-dd_HH:mm");

    private final ChannelStatusService channelStatusService;

    private final ReportingRateRecordsService reportingRateRecordsService;


    /**
     * 逻辑过程：
     * 获取ftp解析的通道进行ftp连接
     * 通过ftp的下载路径下载对应场站和预测厂家目录中的文件到本地目录
     * 进行文件解析
     * 解析成功后，文件上传到minio
     * 将记录存入数据库
     * 备份并删除本地文件（备份文件应定时清理）
     * 解析成功并结束
     */
    public void ftp(ParsingChannel ftpParsingChannel) {

//        List<ParsingChannel> ftpParsingChannels = parsingChannelService.list();
        List<ParsingUrl> ftpParsingUrls = parsingUrlService.list();

        //循环ftp解析通道
//        for (ParsingChannel ftpParsingChannel : ftpParsingChannels) {

            //创建ftp配置
            FtpConfig ftpConfig = new FtpConfig();
            ftpConfig.setHost(ftpParsingChannel.getRemoteIp());
            ftpConfig.setPort(Integer.parseInt(ftpParsingChannel.getRemotePort()));
            ftpConfig.setPassword(ftpParsingChannel.getPassword());
            ftpConfig.setUser(ftpParsingChannel.getUsername());
            //字符集使用UTF-8
            ftpConfig.setCharset(Charset.forName("UTF-8"));
            ftpConfig.setConnectionTimeout(5 * 1000L);

            //ftp连接
            Ftp ftp = ftpConnect(ftpConfig);

            //判断是否连接成功，成功后业务继续
            if (ftp != null) {
                //过滤出当前解析通道下在使用的《 解析路径 》
                List<ParsingUrl> ftpParsingUrlList = ftpParsingUrls.stream().filter(s -> s.getCId().equals(ftpParsingChannel.getId()) && s.getUrlStatus().equals("1")).collect(Collectors.toList());

                try {
                    String dateDir = DateFormatUtils.format(new Date(), "yyyyMMdd");
                    //遍历解析路径，对文件进行解析
                    for (ParsingUrl ftpParsingUrl : ftpParsingUrlList) {
                        String url = ftpParsingUrl.getUrl();
                        // 从ftp下载到本地parsing目录里
                        String path = FileUtil.getParsingPath() + File.separator + ftpParsingUrl.getStationCode() + File.separator + ftpParsingUrl.getForecastManufactor()+File.separator +dateDir;
                        File dirFile = new File(path);
                        if (!dirFile.exists()) {
                            dirFile.mkdirs();
                        }

                        if (ftp.existFile(url)) {
//                            List<FTPFile> ftpFiles = ftp.lsFiles(url, new Filter<FTPFile>() {
//                                @Override
//                                public boolean accept(FTPFile ftpFile) {
//                                    return true;
//                                }
//                            });
                            List<String> strings = ftp.ls(url);
                            //遍历文件
                            for (String fileName : strings) {
//                                if (!fTPFile.isDirectory()) {
//                                    String fileName = fTPFile.getName();
                                ParsingLog parsingLog = new ParsingLog();
                                parsingLog.setFileName(fileName);
                                parsingLog.setStationCode(ftpParsingUrl.getStationCode());
                                parsingLog.setParsingTime(new Date());

                                //下载文件到临时目录
                                ftp.download(url, fileName, dirFile);
                                File file = FileUtils.getFile(dirFile, fileName);

                                //定义解析的类型，默认为错误（未知），成功后为文件类型，也会作为存储目录名
                                String type = parsingFileService.parsingFile(file, ftpParsingUrl);
                                parsingLog.setFileType(type);
                                if (type.startsWith(ParsingConstant.FAIL)) {
                                    // 解析失败
                                    file.delete();
                                    parsingLog.setParsingFileStatus("0");
                                    parsingLog.setParsingDescribe("文件解析失败");
                                }
                                else{
                                    // 解析成功，删除ftp上的文件
                                    ftp.delFile(url + "/" + fileName);
                                    parsingLog.setParsingFileStatus("1");
                                    parsingLog.setParsingDescribe("文件解析成功");
                                }
                                parsingLogService.save(parsingLog);
                            }
                        }
                    }
                    log.info("{}ftp下载文件并解析执行完成", ftpParsingChannel.getChannelName());
                } catch (Exception e) {
                    log.error("{}ftp下载文件并解析过程失败", ftpParsingChannel.getChannelName());
                    e.printStackTrace();
                } finally {
                    try {
                        if (ftp != null) {
                            ftp.close();
                            log.info("{}ftp连接关闭，对端ip：{}", ftpParsingChannel.getChannelName(), ftpParsingChannel.getRemoteIp());
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
//        }
    }

    /**
     * minio 上传文件
     *
     * @param foldPath
     * @param file
     * @return
     */
    public boolean minioUp(String foldPath, File file) {
//        boolean success = Boolean.FALSE;
//        InputStream in = null;
//        try {
//            in = new FileInputStream(file);
//            if (!minioUtilService.bucketExists(bucketName)) {
//                minioUtilService.makeBucket(bucketName);
//            }
//            minioUtilService.putObject(bucketName, foldPath, in);
//            log.info("minio上传文件成功：{}", file.getName());
//            success = Boolean.TRUE;
//        } catch (Exception e) {
//            log.error("minio上传文件失败：{}", file.getName());
//        } finally {
//            try {
//                in.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            return success;
//        }
        return true;
    }

    /**
     * ftp连接
     *
     * @param ftpConfig
     * @return
     */
    public Ftp ftpConnect(FtpConfig ftpConfig) {
        Ftp ftp = null;
        try {
            //设置主动模式连接
            ftp = new Ftp(ftpConfig, FtpMode.Active);
            log.info("{} ：ftp连接成功", ftpConfig.getHost());
        } catch (Exception e) {
            log.error("{} ：获取上送文件ftp连接失败", ftpConfig.getHost());
            e.printStackTrace();
        } finally {
            return ftp;
        }
    }


    /**
     * 对于状态文件单独解析
     *
     * @param file
     * @param parsingUrl
     * @return
     */
    public String parsingStatusFile(File file, ParsingUrl parsingUrl) {

        String parsingStatus = ParsingConstant.FAIL;
        return parsingStatus;
//        try {
//            String str = FileUtil.getStr(file);
//
//            ParsingStatusFileDto parsingStatusFileDto = JsonBeanUtil.jsonToBean(str, ParsingStatusFileDto.class);
//
//            Date date = simpleDateTimeFormat.parse(parsingStatusFileDto.getDate());
//
//            List<ReportingRateRecords> reportingRateRecordsList = new ArrayList<>();
//            for (ReportingRateDto reportingRateDto : parsingStatusFileDto.getReportingRates()) {
//                ReportingRateRecords reportingRateRecords = new ReportingRateRecords();
//
//                reportingRateRecords.setFileType(reportingRateDto.getRateType());
//                reportingRateRecords.setReportingRate(reportingRateDto.getReportrate());
//                reportingRateRecords.setStationCode(ftpParsingUrl.getStationCode());
//                reportingRateRecords.setUploadTime(date);
//
//                reportingRateRecordsList.add(reportingRateRecords);
//            }
//
//            reportingRateRecordsService.saveBatch(reportingRateRecordsList);
//
//
//            List<ChannelStatus> channelStatusList = new ArrayList<>();
//            for (ChannelStatusDto channelStatusDto : parsingStatusFileDto.getChannelStatus()) {
//                ChannelStatus channelStatus = new ChannelStatus();
//                channelStatus.setChannelName(channelStatusDto.getChannelName());
//                channelStatus.setStationCode(ftpParsingUrl.getStationCode());
//                channelStatus.setStatus(channelStatusDto.getStatus());
//                channelStatus.setType(channelStatusDto.getType());
//                channelStatus.setUploadTime(date);
//
//                channelStatusList.add(channelStatus);
//            }
//
//            LambdaQueryWrapper<ChannelStatus> lambdaQueryWrapper = new LambdaQueryWrapper<ChannelStatus>();
//            lambdaQueryWrapper.eq(ChannelStatus::getStationCode,ftpParsingUrl.getStationCode());
//            channelStatusService.remove(lambdaQueryWrapper);
//            channelStatusService.saveBatch(channelStatusList);
//            parsingStatus = "status";
//        } catch (Exception e) {
//            parsingStatus += "status 解析失败";
//            log.error("解析状态数据失败！ /(ㄒoㄒ)/~~", e);
//        }finally {
//            return parsingStatus;
//        }

    }
}
