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().toLowerCase());
                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()!=true).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);
                    List<PageRoute> pageRoutes=new ArrayList<>();
                    for (Measure measure : measures) {
                        PageRoute pageRoute=new PageRoute();
                        pageRoute.setPageName(measure.getUrl());
                        pageRoute.setSuccess(0);
                        if(measure.getSuccess()) {
                            pageRoute.setSuccess(1);
                        }
                        pageRoute.setMessage("无/有");
                        pageRoute.setPicture(measure.getScreenshot());
                        pageRoute.setResponseTime(measure.getResponseTime());
                        pageRoutes.add(pageRoute);
                    }
                    List<String> sourceUrls = getSourceUrls(testChannel, pageContents);
                    List<PageRoute> allPageRoutes = getAllPageRoutes(pageRoutes, sourceUrls);
                    List<PageRoute> collect = allPageRoutes.stream().distinct().collect(Collectors.toList());
                    if(collect!=null&&collect.size()>0){
                        evaReport.setPageRoutes(collect);
                    }else{
                        evaReport.setPageRoutes(pageRoutes);
                    }
                    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,1);
                    WebSocketServer.sendInfo("1,"+id,"sjq110");
                    return;
                }
                autoResultSetService.updateByid(id,2);
                WebSocketServer.sendInfo("2,"+id,"sjq110");
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    autoResultSetService.updateByid(id,2);
                    WebSocketServer.sendInfo("2,"+id,"sjq110");
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }

        }
    }

    private List<String> getSourceUrls(TestChannel testChannel, List<PageContentTest> 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) {
                System.out.println("源码类型:"+fileRoutes);
                List<String> routerList = getRouterList(alls, fileRoutes);
                List<String> collect = routerList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());
                System.out.println("源代码中的路由地址:"+collect.toString());
                FileHtmlUtil.clearAll();
               return collect;
            }
            FileHtmlUtil.clearAll();
        }
        return null;
    }

    private List<String> getRouterList(Map<String, List<FileType>> alls, String fileRoutes) {
        String pattern="(<*\\/:*[a-zA-Z]+)+";
        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{
                            for (FileType fileBean : fileBeans) {
                                if(fileBean.getFileName().contains("router")&&fileBean.getSuffix().equals("js")){
                                    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;
    }

    public static void main(String[] args) {
        List<PageRoute> pageRoutes=new ArrayList<>();
        PageRoute p1=new PageRoute();
        p1.setPageName("http://www.baidu.com/eva/update");
        PageRoute p2=new PageRoute();
        p2.setPageName("/eva/save");
        PageRoute p3=new PageRoute();
        p3.setPageName("http://www.baidu.com/eva/delete");
        PageRoute p4=new PageRoute();
        p4.setPageName("http://www.baidu.com/eva/find");
        PageRoute p5=new PageRoute();
        p5.setPageName("http://www.baidu.com/sff/1/s/10");
        pageRoutes.add(p1);
        pageRoutes.add(p2);
        pageRoutes.add(p3);
        pageRoutes.add(p4);
        pageRoutes.add(p5);

        List<String> urls=Arrays.asList("/save","/find/search","/update","/sdf/hks","/sff/:sdf/s/:size");
        List<PageRoute> pageRouteList=new ArrayList<>();
        List<String> s=new ArrayList<>();
        for (PageRoute pageRoute : pageRoutes) {
            for (String url : urls) {
                if(pageRoute.getPageName().contains(url)){
                    pageRouteList.add(pageRoute);
                    s.add(url);
                }
            }
        }
        List<String> collect = urls.stream().filter(u -> !s.contains(u)).collect(Collectors.toList());
        List<PageRoute> ps = pageRoutes.stream().filter(u -> !pageRouteList.contains(u)).collect(Collectors.toList());
        List<PageRoute> allPageRoutes=new ArrayList<>();
        for (PageRoute pageRoute : pageRouteList) {
            pageRoute.setMessage("有/有");
            allPageRoutes.add(pageRoute);
        }
        for (String s1 : collect) {
            PageRoute pageRoute=new PageRoute();
            pageRoute.setPageName(s1);
            pageRoute.setMessage("有/无");
            pageRoute.setResponseTime(0);
            pageRoute.setSuccess(0);
            allPageRoutes.add(pageRoute);
        }
        for (PageRoute p : ps) {
            p.setMessage("无/有");
            allPageRoutes.add(p);
        }

        allPageRoutes.stream().forEach(System.out::println);
    }

    public List<PageRoute> getAllPageRoutes(List<PageRoute> pageRoutes,List<String> sourceUrls){
        if(pageRoutes==null||pageRoutes.size()==0){
            return null;
        }
        if(sourceUrls==null||sourceUrls.size()==0){
            return pageRoutes;
        }
        List<PageRoute> pageRouteList=new ArrayList<>();
        List<String> s=new ArrayList<>();
        for (PageRoute pageRoute : pageRoutes) {
            for (String url : sourceUrls) {
                if(pageRoute.getPageName().contains(url)){
                    pageRouteList.add(pageRoute);
                    s.add(url);
                }
            }
        }
        List<String> collect = sourceUrls.stream().filter(u -> !s.contains(u)).collect(Collectors.toList());
        List<PageRoute> ps = pageRoutes.stream().filter(u -> !pageRouteList.contains(u)).collect(Collectors.toList());
        List<PageRoute> allPageRoutes=new ArrayList<>();
        for (PageRoute pageRoute : pageRouteList) {
            pageRoute.setMessage("有/有");
            allPageRoutes.add(pageRoute);
        }
        for (String s1 : collect) {
            PageRoute pageRoute=new PageRoute();
            pageRoute.setPageName(s1);
            pageRoute.setMessage("有/无");
            pageRoute.setResponseTime(0);
            pageRoute.setSuccess(0);
            allPageRoutes.add(pageRoute);
        }
        for (PageRoute p : ps) {
            p.setMessage("无/有");
            allPageRoutes.add(p);
        }

        allPageRoutes.stream().forEach(System.out::println);
        return allPageRoutes;
    }


}
