package com.friday.custody.utils;

import com.alibaba.fastjson.JSON;
import com.friday.custody.entity.TenantEmailAuthorizationInfoEntity;
import com.friday.custody.dto.ExtractCallback;
import com.friday.custody.dto.TenantEscrowAuthorizationInfoDto;
import com.sun.mail.imap.IMAPFolder;
import lombok.extern.slf4j.Slf4j;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import org.apache.commons.io.FileExistsException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

@Slf4j
public class MailUtil {

    private static final String DOT = ".";
    public static String NORM_DATETIME_PATTERN = "yyyyMMdd";
    public static final String File_Type_RAR = "rar";
    public static final String File_Type_ZIP = "zip";
    private MimeMessage mimeMessage;
    /**
     * 附件下载后的存放目录
     */
    private String saveAttachPath;
    /**
     * 存放邮件内容的StringBuffer对象
     */
    private StringBuffer bodyText = new StringBuffer();

    /**
     * 构造函数,初始化一个MimeMessage对象
     *
     * @param mimeMessage
     */
    public MailUtil(MimeMessage mimeMessage) {
        this.mimeMessage = mimeMessage;
    }

    /**
     * 获得发件人的地址和姓名
     *
     * @return
     * @throws MessagingException
     */
    public String getFrom() throws MessagingException {
        InternetAddress address[] = (InternetAddress[]) mimeMessage.getFrom();
        String from = address[0].getAddress();
        if (from == null) {
            from = "";
        }
        String personal = address[0].getPersonal();

        if (personal == null) {
            personal = "";
        }

        String fromAddr = null;
        if (personal != null || from != null) {
            fromAddr = personal + "<" + from + ">";
        }
        return fromAddr;
    }

    public static void handleRARFile(File file) {
        log.info("handleRARFile,文件夹为{}",file == null ? "null":file.getAbsolutePath());
        if (file == null){
            return;
        }
        if (!file.exists()) {
            return;
        }

        if(!file.isDirectory()){
            log.error("handleRARFile处理的文件不是文件夹");
        }

        String absolutePath = file.getAbsolutePath();

        //子文件 / 子文件夹
        //File[] files = file.listFiles();
        Collection<File> files = FileUtils.listFiles(file, new String[]{"RAR"}, true);
        if(CollectionUtils.isEmpty(files)){
            return;
        }
        //只用于 RAR文件更改名字
        for (File fileItem : files) {
            String name = fileItem.getName();
            if (!name.contains("RAR")) {
                continue;
            }
            String dateString = StrUtil.getDateStrFromStringByPattern(name, DATE_PATTERN);
            if(!StringUtils.isEmpty(dateString)){
                String targetFilename = absolutePath + File.separator +"ABD" + dateString + ".rar";
                File targetFile = new File(targetFilename);
                for (int i = 0; i < 5; i++) {
                    if(targetFile.exists()){
                        try {
                            //删除 ABDyyyyMMdd.rar
                            targetFile.delete();
                            Thread.sleep(100L);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            log.error("interrupted exception",e);
                        }
                    }else{
                        break;
                    }
                }

                for (int i = 0; i < 10; i++) {
                    if(!fileItem.renameTo(targetFile)){
                        try {
                            Thread.sleep(100L);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            log.error("interrupted exception",e);
                        }
                    }else {
                        break;
                    }
                }
            }
        }
    }

    /**
     * 获得邮件主题
     *
     * @return
     * @throws MessagingException
     * @throws UnsupportedEncodingException
     */
    public String getSubject() throws MessagingException, UnsupportedEncodingException {
        String subject = MimeUtility.decodeText(mimeMessage.getSubject());
        if (subject == null) {
            subject = "";
        }
        return subject;
    }

    /**
     * 获得邮件发送日期
     *
     * @return
     * @throws MessagingException
     */
    public String getSentDate() throws MessagingException {
        Date sentDate = mimeMessage.getSentDate();
        SimpleDateFormat format = new SimpleDateFormat(NORM_DATETIME_PATTERN);
        return format.format(sentDate);
    }

    /**
     * 获得邮件正文内容
     *
     * @return
     */
    public String getBodyText() {
        return bodyText.toString();
    }

    /**
     * 解析邮件，把得到的邮件内容保存到一个StringBuffer对象中，解析邮件
     * 主要是根据MimeType类型的不同执行不同的操作，一步一步的解析
     *
     * @param part
     * @throws MessagingException
     * @throws IOException
     */
    public void getMailContent(Part part) throws MessagingException, IOException {

        String contentType = part.getContentType();

        int nameIndex = contentType.indexOf("name");

        boolean conName = false;

        if (nameIndex != -1) {
            conName = true;
        }

        if (part.isMimeType("text/plain") && conName == false) {
            bodyText.append((String) part.getContent());
        } else if (part.isMimeType("text/html") && conName == false) {
            bodyText.append((String) part.getContent());
        } else if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();
            int counts = multipart.getCount();
            for (int i = 0; i < counts; i++) {
                this.getMailContent(multipart.getBodyPart(i));
            }
        } else if (part.isMimeType("message/rfc822")) {
            this.getMailContent((Part) part.getContent());
        }
    }

    /**
     * 判断此邮件是否需要回执，如果需要回执返回"true",否则返回"false"
     *
     * @return
     * @throws MessagingException
     */
    public boolean getReplySign() throws MessagingException {

        boolean replySign = false;

        String needReply[] = mimeMessage.getHeader("Disposition-Notification-To");

        if (needReply != null) {
            replySign = true;
        }
        return replySign;
    }

    /**
     * 判断此邮件是否已读，如果未读返回false,反之返回true
     *
     * @return
     * @throws MessagingException
     */
    public boolean isNew() throws MessagingException {
        boolean isNew = false;
        Flags flags = mimeMessage.getFlags();
        Flags.Flag[] flag = flags.getSystemFlags();
        for (int i = 0; i < flag.length; i++) {
            if (flag[i] == Flags.Flag.SEEN) {
                isNew = true;
            }
        }
        return isNew;
    }

    /**
     * 判断此邮件是否包含附件
     *
     * @param part
     * @return
     * @throws MessagingException
     * @throws IOException
     */
    public boolean isContainAttach(Part part) throws MessagingException, IOException {
        boolean attachFlag = false;
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            BodyPart mPart;
            String conType;
            for (int i = 0; i < mp.getCount(); i++) {
                mPart = mp.getBodyPart(i);
                String disposition = mPart.getDisposition();
                if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) {
                    attachFlag = true;
                } else if (mPart.isMimeType("multipart/*")) {
                    attachFlag = this.isContainAttach(mPart);
                } else {
                    conType = mPart.getContentType();
                    if (conType.toLowerCase().indexOf("application") != -1 || conType.toLowerCase().indexOf("name") != -1) {
                        attachFlag = true;
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            attachFlag = isContainAttach((Part) part.getContent());
        }
        return attachFlag;
    }

    /**
     * 保存附件
     *
     * @param part
     * @param attachKey
     * @throws MessagingException
     * @throws IOException
     */
    public void saveAttachMent(Part part, String attachKey) throws MessagingException, IOException {
        String fileName;
        if (part.isMimeType("multipart/*")) {
            Multipart mp = (Multipart) part.getContent();
            BodyPart mPart;
            for (int i = 0; i < mp.getCount(); i++) {
                mPart = mp.getBodyPart(i);
                String disposition = mPart.getDisposition();
                if (Part.ATTACHMENT.equals(disposition) || Part.INLINE.equals(disposition)) {
                    fileName = mPart.getFileName();
                    if (null != fileName && fileName.toLowerCase().indexOf("gb2312") != -1) {
                        fileName = MimeUtility.decodeText(fileName);
                    }
                    if (StringUtils.isNotBlank(attachKey)) {
                        String realFileName = decodeText(fileName);
                        if (StringUtils.isBlank(realFileName)) {
                            log.info("附件文件名为空，不能满足附件关键字筛选，跳过！！！");
                            continue;
                        }
                        if (!attachKey.contains(",") && !realFileName.contains(attachKey)) {
                            log.info("当前附件不符合附件关键字：{}，跳过！！！", attachKey);
                            continue;
                        }
                        if (attachKey.contains(",") && Arrays.stream(attachKey.split(",")).noneMatch(realFileName::contains)) {
                            log.info("当前附件不符合附件关键字：{}，跳过！！！", attachKey);
                            continue;
                        }
                    }
                    this.saveFile(decodeText(fileName), mPart.getInputStream());
                } else if (mPart.isMimeType("multipart/*")) {
                    this.saveAttachMent(mPart, attachKey);
                } else {
                    fileName = mPart.getFileName();
                    if ((fileName != null) && (fileName.toLowerCase().indexOf("GB2312") != -1)) {
                        fileName = MimeUtility.decodeText(fileName);
                        if (StringUtils.isNotBlank(attachKey)) {
                            String realFileName = decodeText(fileName);
                            if (StringUtils.isBlank(realFileName)) {
                                log.info("附件文件名为空，不能满足附件关键字筛选，跳过！！！");
                                continue;
                            }
                            if (!attachKey.contains(",") && !realFileName.contains(attachKey)) {
                                log.info("当前附件不符合附件关键字：{}，跳过！！！", attachKey);
                                continue;
                            }
                            if (attachKey.contains(",") && Arrays.stream(attachKey.split(",")).noneMatch(realFileName::contains)) {
                                log.info("当前附件不符合附件关键字：{}，跳过！！！", attachKey);
                                continue;
                            }
                        }
                        this.saveFile(decodeText(fileName), mPart.getInputStream());
                    }
                }
            }
        } else if (part.isMimeType("message/rfc822")) {
            this.saveAttachMent((Part) part.getContent(), attachKey);
        }
    }

    /**
     * 设置附件存放路径
     *
     * @param attachPath
     */
    public void setAttachPath(String attachPath) {
        this.saveAttachPath = attachPath;
    }

    /**
     * 获得附件存放路径
     *
     * @return
     */
    public String getAttachPath() {
        return saveAttachPath;
    }

    /**
     * 真正的保存附件到指定目录里
     *
     * @param fileName
     * @param in
     * @throws IOException
     */
    private void saveFile(String fileName, InputStream in) throws IOException {
        String storeDir = this.getAttachPath();

        log.info("storeDir:{},fileName={}",  storeDir,fileName);
        if(StringUtils.isEmpty(storeDir)){
            storeDir = "/nas_data/work/temp/email/";
        }
        File file = new File(storeDir);
        if(!file.exists()){
            file.mkdirs();
        }
        //保存文件时, 都改为小写
        FileOutputStream fos = new FileOutputStream(new File(storeDir + File.separator + fileName.toLowerCase()));
        IOUtils.copy(in, fos);
        IOUtils.closeQuietly(fos);
        IOUtils.closeQuietly(in);
    }

    /**
     * 获取163邮箱信息
     *
     * @param host
     * @param username
     * @param password
     * @param protocol
     * @return
     * @throws MessagingException
     */
    public static Message[] getWEMessage(String host, String username, String password, String protocol) throws MessagingException {
        //创建属性对象
        Properties props = System.getProperties();
        props.setProperty("mail.store.protocol", protocol);
//        props.setProperty("mail.imap.host", host);
        props.setProperty("mail.host", host);
//        props.setProperty("mail.pop3s.port", "995");
        //创建会话
//        Session session = Session.getInstance(props);
        Session session = Session.getDefaultInstance(props, null);
        //存储对象
        Store store = session.getStore(protocol);
        //连接
        store.connect(host, username, password);
        //创建目录对象
        Folder folder = store.getFolder("INBOX");
        if (folder instanceof IMAPFolder) {
            IMAPFolder imapFolder = (IMAPFolder) folder;
            /*//javamail中使用id命令有校验checkOpened, 所以要去掉id方法中的checkOpened();
            imapFolder.doCommand(new IMAPFolder.ProtocolCommand() {
                public Object doCommand(IMAPProtocol p) throws com.sun.mail.iap.ProtocolException {
                    p.id("FUTONG");
                    return null;
                }
            });*/
        }
        Message[] messages = null;
        if (folder != null) {
            folder.open(Folder.READ_WRITE);
            messages = folder.getMessages();
            log.info("邮件总数量:" + messages.length);
        }
        return messages;
    }

    /**
     * 获取163邮箱信息
     *
     * @return
     * @throws MessagingException
     */
    public static Message[] getMessageByTenantEmail(TenantEmailAuthorizationInfoEntity tenantEmail) {
        try {                                             //创建属性对象
            Properties props = new Properties();
            props.setProperty("mail.transport.protocol", tenantEmail.getEmailAgreement());
            props.setProperty("mail.host", tenantEmail.getEmailHost());
            props.setProperty("mail.user", tenantEmail.getEmailAddress());
            props.setProperty("mail.from", tenantEmail.getFromEmail());
            Session session = Session.getDefaultInstance(props, null);
            //存储对象
            Store store = null;

            store = session.getStore(tenantEmail.getEmailAgreement());

            //连接
            store.connect(tenantEmail.getEmailHost(), tenantEmail.getEmailAddress(), tenantEmail.getEmailSecret());
            //创建目录对象
            Folder folder = store.getFolder("INBOX");

            Message[] messages = null;
            if (folder != null) {
                folder.open(Folder.READ_WRITE);
                messages = folder.getMessages();
                log.info("邮件总数量:" + messages.length);
            }else{
                log.warn("getMessageByTenantEmail_folder为null");
            }
            return messages;
        } catch (Exception e){
            log.error("getMessageByTenantEmail",e);
        }
        return new Message[]{};
    }


    /**
     * 打印邮件
     *
     * @param messageList
     * @param attachKey
     * @throws IOException
     * @throws MessagingException
     */
    public static void printMailMessage(List<Message> messageList, String filePath, String attachKey) throws IOException, MessagingException {
        log.info("邮件数量:" + messageList.size());
        MailUtil re;
        Message message;
        for (int i = 0, leng = messageList.size(); i < leng; i++) {
            message = messageList.get(i);
            re = new MailUtil((MimeMessage) message);
            log.info("邮件[" + i + "]主题:" + re.getSubject());
            String sentDate = re.getSentDate();
            log.info("邮件[" + i + "]发送时间:" + sentDate);
            // 下载到/filePath目录下或默认目录/nas_data/work/temp/email/
            re.setAttachPath(filePath);
            re.saveAttachMent(message, attachKey);
            // 将/filePath下下载的 txt文件 转移到/filePath/ABDsentdate/目录下，目前看下来没啥用
            moveTxtToDailyDirIfExistDate(sentDate,filePath);
        }
    }

    private static void moveTxtToDailyDirIfExistDate(String sentDate, String filePath) {
        if (org.apache.commons.lang.StringUtils.isEmpty(sentDate)) {
            log.info("moveTxtToDailyDirIfExistDate:无法从邮件获取时间!");
            return;
        }
        String dailyDir = filePath + File.separator + "ABD" + sentDate;
        File dir = new File(dailyDir);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                log.info("创建文件夹失败!");
                return;
            }
        }
        File file = new File(filePath);
        String[] extension = {"txt", "TXT", "Txt"};

        //先把目标文件夹清空再处理
        log.info("先把目标文件夹清空再处理 目标文件夹{}", dir == null ? "null" : dir.getAbsolutePath());
        Collection<File> filesOld = FileUtils.listFiles(dir, extension, false);
        if (!CollectionUtils.isEmpty(filesOld)) {
            for (File file1 : filesOld) {
                for (int i = 0; i < 3; i++) {
                    if (file1.delete()) {
                        break;
                    }
                    try {
                        Thread.sleep(100L);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        log.error("interrupted exception",e);
                    }
                }
            }
        }

        //再把新加的落进去
        Collection<File> files = FileUtils.listFiles(file, extension, false);
        //这天没有文件，把目标文件夹也删了吧
        if (CollectionUtils.isEmpty(files)) {
            log.info("{}文件夹为空，删除目标文件夹{}", file == null ? "null" : file.getAbsolutePath(), dir == null ? "null" : dir.getAbsolutePath());
            for (int i = 0; i < 3; i++) {
                if (dir.delete()) {
                    break;
                }
                try {
                    Thread.sleep(100L);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log.error("interruptedException",e);
                }
            }
        }
        //移动文件到指定文件夹
        for (File file1 : files) {
            log.info("移动文件:{}到指定文件夹{}", file1.getName(), dir);
            try {
                File file2 = new File(
                        StringUtils.substringBeforeLast(file1.getAbsolutePath(), "/")
                                + "/" + StringUtils.substringAfterLast(file1.getAbsolutePath(), "/").toLowerCase());
                file1.renameTo(file2);
                FileUtils.moveToDirectory(file2, dir, true);
            } catch (FileExistsException e) {
                log.info("moveTxtToDailyDirIfExistDate 文件已经存在！");
            } catch (Exception e) {
                log.error("", e);
            }
        }
    }

    public static List<Message> getMail(TenantEmailAuthorizationInfoEntity emailConfig, String date) throws MessagingException, IOException, ParseException {
        //获取文件之前删除文件夹内的所有文件
        //FileUtil.deleteFile(new File(filePath));
        //只读取该邮箱发来的邮件
        String fromMail = emailConfig.getFromEmail();
        String filePath = emailConfig.getDirFilePath();
        //只读取该日期以后的邮件
        String startDate;
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        if (!StringUtils.isEmpty(date)) {
            startDate = date;
        } else {
            startDate = format.format(new Date());
        }
        Message[] weMessage = getWEMessage(emailConfig.getEmailHost(), emailConfig.getEmailAddress(), emailConfig.getEmailSecret(), emailConfig.getEmailAgreement());
//        //方便测试
//        Message[] filterMessage = new Message[800];
//        System.arraycopy(weMessage, weMessage.length - 2000, filterMessage, 0, 800);
        // 筛选邮件
        List<Message> messages = filterMessage(weMessage,
                fromMail,
                startDate,
                emailConfig.getEmailSubject(),
                Boolean.TRUE);
        if (CollectionUtils.isEmpty(messages)) {
            log.info("账号配置为：{}的未筛选到符合邮件", JSON.toJSONString(emailConfig));
            return new ArrayList<>();
        }
        // 创建配置的路径文件夹
        log.info("filePath:" + filePath);
        File file = new File(filePath);
        if(!file.exists() || !file.isDirectory()){
            if (!file.mkdirs()) {
                log.info("创建文件夹{}失败",file.getAbsolutePath());
            }
        }
        // 打印邮件，下载txt文件到/filePath/ABDsentdate/目录下 其他文件到/filePath目录下
        printMailMessage(messages, filePath, emailConfig.getAttachKey());
        return messages;
        // 没看懂这是干啥，好像没意义
//        String path;
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
//        LocalDate startDateWithTar = LocalDate.parse(date, dateTimeFormatter);
//        LocalDate now = LocalDate.now();
//        List<String> result = new ArrayList<>();
//        if(now.isBefore(startDateWithTar)){
//            path = filePath + File.separator + "ABD" + format.format(new Date()) + ".rar";
//            result.add(path);
//        }else{
//            while(!now.isBefore(startDateWithTar)){
//                date = dateTimeFormatter.format(startDateWithTar);
//                path = filePath + File.separator + "ABD" + date + ".rar";
//                startDateWithTar = startDateWithTar.plusDays(1L);
//                result.add(path);
//            }
//        }
//
//        log.info("paths:" + JSON.toJSONString(result));
    }


    /**
     * 打印邮件
     *
     * @param message
     * @throws IOException
     * @throws MessagingException
     */
    public static void printMailInfo(Message message, String filePath, TenantEscrowAuthorizationInfoDto tenant) throws IOException, MessagingException {
        MailUtil re;

        re = new MailUtil((MimeMessage) message);
        log.info("***邮件主题***:" + re.getSubject());
            log.info("***邮件发送时间***:" + re.getSentDate());
        log.info("***邮件是否包含附件***:" + re.isContainAttach(message));
        log.info("***邮件发送人地址***:" + re.getFrom());
        re.getMailContent(message);
//        log.info("邮件正文内容:\r\n" + re.getBodyText());
        // todo 原来是注解 ,这是保存附近到本地的方法
        /*re.setAttachPath(filePath);
        re.saveAttachMent(message);*/
    }


    public static final String DATE_PATTERN = "yyyyMMdd";

    /**
     * 邮箱从最近到从前
     * @param message 邮件
     * @param fromMail 发送地址
     * @param startDate 筛选时间，拿到这个时间点之后的邮箱
     * @param emailSubject 邮箱主题 关键字或者正则表达式
     * @param isFromThePresentToPast 是从最近到以前吗
     * @return
     * @throws ParseException
     */
    public static List<Message> filterMessage(Message[] message, String fromMail, String startDate, String emailSubject,boolean isFromThePresentToPast) throws ParseException, MessagingException {
        log.info("filterMessage:message.length={},fromMail={},startDate={},emailSubject={}",message==null?0:message.length,fromMail,startDate,emailSubject);
        List<Message> collect = new ArrayList<>();
        if (message == null || message.length == 0) {
            log.info("过滤邮件：入参邮件数组为空！");
            return collect;
        }
        List<Message> messages = Arrays.asList(message);
        //邮件从最近到从前，逆转一下
        if(isFromThePresentToPast){
            Collections.reverse(messages);
        }
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN);
        long startTime = sdf.parse(startDate).getTime();
        //转化为小写,防止大小写不一致情况
        if (fromMail != null) {
            fromMail = fromMail.toLowerCase();
        }
        for (Message message1 : messages) {
            //判断连接是否关闭
            if(!message1.getFolder().isOpen()){
                try {
                    message1.getFolder().open(Folder.READ_ONLY);
                } catch (MessagingException e) {
                    log.error("当前邮件连接失败!", e);
                    continue;
                }
            }
            Address[] mailFroms;
            try {
                mailFroms = message1.getFrom();
            } catch (MessagingException e) {
                log.error("邮件主题为{}获得邮件发件人失败!", message1.getSubject(), e);
                continue;
            }
            try {
                if (ObjectUtils.isEmpty(mailFroms)){
                    continue;
                }
                String from = decodeText(mailFroms[0].toString()).toLowerCase();
                String subject = message1.getSubject();
                log.info("发送主题：{},发送时间为{},发送人为{}", subject,message1.getSentDate(), message1.getFrom());
                // 有的邮箱发送时间为空，但是还是有发送时间的提前用发送时间判断一下
                // 发送时间校验
                Date sentDate = message1.getSentDate();
                if(isFromThePresentToPast){
                    if (sentDate != null) {
                        if (sentDate.getTime() < startTime) {
                            log.info("该邮件主题为{}，发送时间为{}，早于开始时间{}，过滤", subject, sentDate, startDate);
                            break;
                        }
                    } else {
                        // 从主题名称中获取时间，旧逻辑如此，此处为优化原来代码
                        Date dateFromStringByPattern = StrUtil.getDateFromStringByPattern(subject, DATE_PATTERN);
                        if (dateFromStringByPattern == null || dateFromStringByPattern.getTime() < startTime) {
                            log.info("该邮件主题为{}，从主题中获取到时间{}，跳过", subject, dateFromStringByPattern);
                            continue;
                        }
                    }
                }
                // 校验发件人
                if (StringUtils.isNotBlank(fromMail) && !from.contains(fromMail)) {
                    log.info("当前邮件主题：{}，当前邮件发送人为：{}，不符合筛选发送人：{}，跳过", subject, from, fromMail);
                    continue;
                }
                // 校验主题
                if (StringUtils.isNotBlank(emailSubject)) {
                    boolean hasContinue = true;
                    // 没有英文,的
                    if (subject.contains(emailSubject)) {
                        hasContinue = false;
                    }
                    // 正则的
                    if (Pattern.matches(emailSubject, subject)) {
                        hasContinue = false;
                    }
                    // 检验是否多个使用英文,隔开的
                    if (emailSubject.contains(",")) {
                        String[] subjectList = emailSubject.split(",");
                        if (Arrays.stream(subjectList).anyMatch(subject::contains)) {
                            hasContinue = false;
                        }
                    }
                    if (hasContinue) {
                        log.info("当前邮件主题：{}，当前邮件主题为：{}，不符合筛选主题：{}，跳过", subject, subject, emailSubject);
                        continue;
                    }
                }
                collect.add(message1);
            } catch (Exception e) {
                log.error("筛选邮件失败!", e);
            }
        }
        log.info("确定邮件数量{}", collect.size());
        return collect;
    }

    /**
     * @param newFile        rar文件路径
     * @param targetFilePath 要解压的路径
     */

    public static void unRar(File newFile, String targetFilePath) {
        //如果已经解压过了就不管了
        File file = new File(targetFilePath);
        if(file.exists() && file.isDirectory() && file.list()!=null && file.list().length>0){
            log.info("已经解压过文件夹{}，跳过",targetFilePath);
            return;
        }

        RandomAccessFile randomAccessFile = null;
        IInArchive inArchive = null;
        try {
            // 第一个参数是需要解压的压缩包路径，第二个参数参考JdkAPI文档的RandomAccessFile
            randomAccessFile = new RandomAccessFile(newFile.getPath(), "r");
            inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
            int[] in = new int[inArchive.getNumberOfItems()];
            for (int i = 0; i < in.length; i++) {
                in[i] = i;
            }
//        inArchive.extract(in, true, new ExtractZipFileCallback(inArchive, targetFilePath));
            inArchive.extract(in, false, new ExtractCallback(inArchive, targetFilePath));
            log.info("解压完成");
        } catch (IOException e) {
            e.getStackTrace();
        } finally {
            if (randomAccessFile != null) {
                try {
                    randomAccessFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inArchive != null) {
                try {
                    inArchive.close();
                } catch (SevenZipException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 文本解码
     *
     * @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本
     * @return 解码后的文本
     * @throws UnsupportedEncodingException
     */
    public static String decodeText(String encodeText) throws UnsupportedEncodingException {
        if (encodeText == null || "".equals(encodeText)) {
            return "";
        } else {
            return MimeUtility.decodeText(encodeText);
        }
    }


}
