package com.zjty.autotest.mq;

import com.alibaba.fastjson.JSON;
import com.zjty.autotest.dao.AutoResultSetDao;
import com.zjty.autotest.pojo.report.ElementDetail;
import com.zjty.autotest.pojo.report.Measure;
import com.zjty.autotest.pojo.report.Report;
import com.zjty.autotest.pojo.sjq.*;
import com.zjty.autotest.pojo.test.Input;
import com.zjty.autotest.pojo.test.Project;
import com.zjty.autotest.service.AutoResultSetService;
import com.zjty.autotest.service.TestReportService;
import com.zjty.autotest.service.impl.SeleniumExecutor;
import com.zjty.autotest.util.FileHtmlUtil;
import com.zjty.autotest.util.IdWorker;
import com.zjty.autotest.util.UnZipRarUtil;
import com.zjty.autotest.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
@Slf4j
public class TestTask {
    @Autowired
    private AutoResultSetService autoResultSetService;
    @Autowired
    private TestReportService testReportService;
    @Autowired
    private SeleniumExecutor seleniumExecutor;
    private static Object o=new Object();
    @Scheduled(cron = "0/5 * * * * ?")
    @Async("asyncServiceExecutor")
    public void getMessage() {
        synchronized (o) {
            String take = QueueManager.take();
            log.info("获取到消息:{}", take);
            if (!StringUtils.isEmpty(take)) {
                doBusiness(take);
            }
        }
    }

    private void doBusiness(String id) {


        TestChannel testChannel = (TestChannel) CacheManager.getCache(id);
        if (testChannel != null) {
            log.info("testChannel不为空:{}", testChannel);
            try {
                Project project=new Project();
                project.setBrowser(testChannel.getBrowser());
                project.setName(testChannel.getName());
                project.setUrl(testChannel.getUrl());
                List<RuleSet> ruleSets = testChannel.getRuleSets();
                List<Input> inputs=new ArrayList<>();
                project.setInputs(null);
                if(ruleSets!=null) {
                    for (RuleSet ruleSet : ruleSets) {
                        Input input=new Input();
                        input.setKey(ruleSet.getDes());
                        input.setAttrName(ruleSet.getCommand());
                        input.setAttrValue(ruleSet.getTarget());
                        input.setValue(ruleSet.getValue());
                        inputs.add(input);
                    }
                    project.setInputs(inputs);
                }


                //调用黄承天代码
                Report report = seleniumExecutor.execute(project);
                System.out.println(report);
                List<Measure> measures = report.getMeasures();
                if(measures!=null&&measures.size()>0) {
                    long count = measures.stream().filter(m -> !m.getSuccess()).count();
                    System.out.println(report);
                    EvaReport evaReport = new EvaReport();
                    evaReport.setBrowser(report.getBrowser());
                    if (count > 0) {
                        evaReport.setFailCount(testChannel.getName() + "系统未通过测试，" + "未通过测试点共" + count + "个");
                    }
                    evaReport.setFailCount(testChannel.getName() + "系统通过测试，" + "未通过测试点共0个");
                    evaReport.setProjectName(report.getProjectName());
                    evaReport.setCreateTime(new Date());
                    evaReport.setSystem("中标麒麟v7龙芯版");
                    evaReport.setUrl(testChannel.getUrl());
                    List<FailMessage> failMessages = new ArrayList<>();
                    List<Measure> measureList = measures.stream().filter(m -> !m.getSuccess()).collect(Collectors.toList());
                    for (Measure measure : measureList) {
                        FailMessage failMessage = new FailMessage();
                        failMessage.setUrl(measure.getUrl());
                        failMessage.setMessage(measure.getMessage());
                        failMessage.setPicture(measure.getScreenshot());
                        failMessages.add(failMessage);
                    }
                    evaReport.setFailMessages(failMessages);
                    evaReport.setPageRoutes(null);
                    HashMap<String, Measure> map = new HashMap<>();


                    List<PageContentTest> pageContents = new ArrayList<>();
                    for (Measure measure : measures) {
                        PageContentTest pageContentTest = new PageContentTest();
                        pageContentTest.setUrl(measure.getUrl());
                        pageContentTest.setMessage(measure.getMessage());
                        pageContentTest.setResponseTime(measure.getResponseTime());
                        pageContentTest.setScreenshot(measure.getScreenshot());
                        pageContentTest.setSuccess(0);
                        if(measure.getSuccess()) {
                            pageContentTest.setSuccess(1);
                        }
                        List<ElementDetail> elementDetails = measure.getElementDetails();
                        if(elementDetails!=null) {
                            List<PageContent> contents = new ArrayList<>();
                            for (ElementDetail elementDetail : elementDetails) {
                                PageContent pageContent = new PageContent();
                                pageContent.setParms(elementDetail.getType());
                                pageContent.setMessage(elementDetail.getMessage());
                                pageContent.setResponseTime(elementDetail.getResponseTime());
                                pageContent.setSuccess(0);
                                if (elementDetail.getSuccess()) {
                                    pageContent.setSuccess(1);
                                }
                                contents.add(pageContent);
                            }
                            pageContentTest.setContents(contents);
                        }
                        pageContents.add(pageContentTest);
                    }
                    evaReport.setPageContents(pageContents);


                    if (testChannel.getCodeUrl() != null) {
                        //解压上传得代码

                        FileHtmlUtil.getFiles(testChannel.getCodeUrl(), null);
                        Map<String, List<FileType>> alls = FileHtmlUtil.getAlls();

                        //获取项目类型
                        FileHtmlUtil.getFileRoutes(testChannel.getCodeUrl());
                        int jspcount = FileHtmlUtil.jspNum;
                        int jscount = FileHtmlUtil.jsNum;
                        int vuecount = FileHtmlUtil.vueNum;
                        int angularcount = FileHtmlUtil.angularNum;
                        int htmlcount = FileHtmlUtil.count;
                        String fileRoutes = null;
                        if (jspcount > 0) {
                            fileRoutes = "jsp";
                        } else if (vuecount > 0) {
                            fileRoutes = "vue";
                        } else if (jscount > 0) {
                            fileRoutes = "react";
                        } else if (angularcount > 0) {
                            fileRoutes = "angular";
                        }
                        if (fileRoutes != null) {
                            Map<String,List<PageRoute>> routemap=new HashMap<>();
                            List<String> routerList = getRouterList(alls, fileRoutes);
                            List<String> collect = routerList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());
                            System.out.println(collect.toString());
                            if(collect!=null) {

                                if(pageContents!=null) {
                                    for (String s : collect) {
                                        if(routemap.get(s)==null) {
                                            routemap.put(s, null);
                                        }
                                        for (PageContentTest pageContent : pageContents) {
                                            if(pageContent.getUrl().contains(s)){
                                                List<PageRoute> pageRoutes=new ArrayList<>();
                                                PageRoute route=new PageRoute();
                                                route.setAddress(s);
                                                route.setPageName(pageContent.getUrl());
                                                route.setSuccess(pageContent.getSuccess());
                                                route.setResponseTime(pageContent.getResponseTime());
                                                route.setPicture(pageContent.getScreenshot());
                                                route.setMessage(pageContent.getMessage());
                                                pageRoutes.add(route);
                                                List<PageRoute> ps = routemap.get(s);
                                                if(ps!=null){
                                                    ps.add(route);
                                                    routemap.put(s,ps);
                                                }else{
                                                    routemap.put(s,pageRoutes);
                                                }
                                            }

                                        }
                                    }

                                }
                            }
                        }


                        FileHtmlUtil.clearAll();
                        //获取前端代码中得网页路由地址
                        //比对黄承天代码中访问得地址和路由地址，黄承天是否访问全了。
                    }
                    System.out.println("修改状态");
                    //改变报告状态
                    String out = JSON.toJSONString(evaReport);

                    System.out.println(id);
                    TestReport testReport = new TestReport();
                    testReport.setResultId(id);
                    testReport.setOutReport(out);

                    testReportService.update(testReport);
                    autoResultSetService.updateByid(id);
                    WebSocketServer.sendInfo("测试完成,"+id,"sjq110");
                }
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    WebSocketServer.sendInfo("测试失败,"+id,"sjq110");
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }

        }
    }

    private List<String> getRouterList(Map<String, List<FileType>> alls, String fileRoutes) {
        String pattern="(\\/:*[a-zA-Z0-9]+)+";
        List<String> allRouters = new ArrayList<>();
        Set<String> all = alls.keySet();
        if(all!=null) {
            //所有的路由
            if (fileRoutes.equals("vue")) {
                for (String s1 : all) {
                    List<FileType> fileBeans = alls.get(s1);
                    if (fileRoutes != null) {
                        if (s1.contains("router")) {
                            for (FileType fileBean : fileBeans) {
                                allRouters.addAll(FileHtmlUtil.readTxtFile(fileBean.getAddress(), pattern));
                            }
                        }
                    }
                }
            } else if (fileRoutes.equals("angular") || fileRoutes.equals("react")) {
                for (String s1 : all) {
                    List<FileType> fileBeans = alls.get(s1);
                    if (fileRoutes != null) {
                        for (FileType fileBean : fileBeans) {
                            if (fileBean.getSuffix().equals("js")) {
                                allRouters.addAll(FileHtmlUtil.readTxtFile(fileBean.getAddress(), pattern));
                            }
                        }
                    }
                }
            } else {
                for (String s1 : all) {
                    List<FileType> fileBeans = alls.get(s1);
                    if (fileRoutes != null) {
                        for (FileType fileBean : fileBeans) {
                            if (fileBean.getSuffix().equals("jsp")) {
                                allRouters.addAll(FileHtmlUtil.readTxtFile(fileBean.getAddress(), pattern));
                            }
                        }
                    }
                }
            }
        }
        return allRouters;
    }


}
