package org.jeecg.modules.demo.linkchainerrordetection.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.demo.externalinternalsite.entity.ExternalInternalSite;
import org.jeecg.modules.demo.externalinternalsite.service.IExternalInternalSiteService;
import org.jeecg.modules.demo.linkcaptureerrorlog.service.ILinkCaptureErrorLogService;
import org.jeecg.modules.demo.linkchainerrordetection.entity.LinkChainErrorDetection;
import org.jeecg.modules.demo.linkchainerrordetection.service.ILinkChainErrorDetectionService;
import org.jeecg.modules.demo.linkchainerrorlog.entity.LinkChainErrorLog;
import org.jeecg.modules.demo.linkchainerrorlog.service.ILinkChainErrorLogService;
import org.jeecg.modules.demo.linkerrorstatistics.entity.LinkErrorStatistics;
import org.jeecg.modules.demo.linkerrorstatistics.service.ILinkErrorStatisticsService;
import org.jeecg.modules.demo.linkouterchaindetection.entity.LinkOuterChainDetection;
import org.jeecg.modules.demo.linkouterchaindetection.service.ILinkOuterChainDetectionService;
import org.jeecg.modules.demo.linkouterchainlog.entity.LinkOuterChainLog;
import org.jeecg.modules.demo.linkouterchainlog.service.ILinkOuterChainLogService;
import org.jeecg.modules.demo.linkouterouterstatistics.entity.LinkOuterouterStatistics;
import org.jeecg.modules.demo.linkouterouterstatistics.service.ILinkOuterouterStatisticsService;
import org.jeecg.modules.demo.mainsite.entity.MainSite;
import org.jeecg.modules.demo.mainsite.service.IMainSiteService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

/**
 * 示例带参定时任务
 * 
 * @Author Scott
 */
@Slf4j
@Component
public class LinkChainErrorDetectionParamJob{

	/**
	 * 若参数变量名修改 QuartzJobController中也需对应修改
	 */
	private String parameter;

	@Autowired
	private ILinkChainErrorDetectionService linkChainErrorDetectionService;
	@Autowired
	private IMainSiteService iMainSiteService;

	@Autowired
	private IExternalInternalSiteService externalInternalSiteService;

	@Autowired
	private ILinkOuterChainDetectionService linkOuterChainDetectionService;

	@Autowired
	private ILinkCaptureErrorLogService iLinkCaptureErrorLogService;

	@Autowired
	private ILinkChainErrorLogService iLinkChainErrorLogService;

	@Autowired
	private ILinkErrorStatisticsService iLinkErrorStatisticsService;

	private Integer ThreadpageNum = 0;

	public synchronized boolean  execute(String parameter) throws JobExecutionException {
		this.parameter = parameter;
		try {
			String TenantId = this.parameter.split("&&&")[1];
			this.parameter =  this.parameter.split("&&&")[0];
			log.info( String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob !   时间:" + DateUtils.now(), this.parameter));
			QueryWrapper<MainSite> mainSiteQueryWrapper = new QueryWrapper<MainSite>();
			Page<MainSite> page = new Page<MainSite>(1, 1);
			System.out.println(this.parameter);
			System.out.println(iMainSiteService.list());
			mainSiteQueryWrapper.eq("main_site_url",this.parameter);
			TenantContext.setTenant(TenantId);
			Page<MainSite> page1 = iMainSiteService.page(page, mainSiteQueryWrapper);
			log.info(page1.getRecords()+"");
			MainSite mainSite = null;
			if(page1.getRecords().size() >= 1){
				mainSite = page1.getRecords().get(0);
			}
			log.info(mainSite+"");
			Map<String,ExternalInternalSite> stringExternalInternalSiteMap = new HashMap<String,ExternalInternalSite>();
			if(!ObjectUtils.isEmpty(mainSite)){
				Integer threadNumber = mainSite.getThreadNumber();
				//将对应的扫描列表的起始页分为上述的
				if(threadNumber > 1){
					multithreading(threadNumber,mainSite,TenantId);
				}
				if(threadNumber == 1 || threadNumber == 0){
					onethreading(mainSite,TenantId);
				}
			}
			try {
				TenantContext.setTenant(TenantId);
				//统计数据
				LinkErrorStatistics linkErrorStatistics = iLinkErrorStatisticsService.listCountByMainUrl(mainSite.getMainSiteUrl());
				if(!org.springframework.util.ObjectUtils.isEmpty(linkErrorStatistics)){
					linkErrorStatistics.setId(IdWorker.getIdStr());
					linkErrorStatistics.setTestType("1");
					linkErrorStatistics.setScanTime(linkErrorStatistics.getUpdateTime());
					linkErrorStatistics.setTenantId(Integer.parseInt(TenantId));
					iLinkErrorStatisticsService.save(linkErrorStatistics);
				}
			}catch (Exception e){
				e.printStackTrace();
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return true;
	}
	public void onethreading(MainSite mainSiteMM,String TenantId ){
		String mainUrl = mainSiteMM.getMainSiteUrl();
		if(org.springframework.util.ObjectUtils.isEmpty(mainUrl) || mainUrl == "" || mainUrl == null){
			mainUrl = "http://www.hetaodaxue.com/hyywxx/";
		}
		TenantContext.setTenant(TenantId);
		Integer count =  externalInternalSiteService.countSourceLinkError(mainUrl);
		Integer pageSize = 100;
		Integer pageNum = (int)Math.ceil((double)count/pageSize);
		for(int i = 1; i <= pageNum;i+=1){
			Page<ExternalInternalSite> page = new Page<ExternalInternalSite>(i, pageSize);
			TenantContext.setTenant(TenantId);
			IPage<ExternalInternalSite> pageList = externalInternalSiteService.pageSourceErrorMainUrl(page,mainUrl);
			for (ExternalInternalSite internalSite : pageList.getRecords()){
				//爬取页面
				Document document = null;
				try {
					document = Jsoup.parse(new URL(internalSite.getUrl()), 10000);
				}catch (Exception e){

				}
				if(!ObjectUtils.isEmpty(document)){
					continue;
				}
				LinkChainErrorDetection errorDetection = new LinkChainErrorDetection();
				errorDetection.setId(DigestUtils.md5DigestAsHex(internalSite.getUrl().getBytes()));
				errorDetection.setCreateBy(internalSite.getMainUrl());
				errorDetection.setCreateTime(new Date());
				errorDetection.setUpdateBy(internalSite.getMainUrl());
				errorDetection.setUpdateTime(new Date());
				QueryWrapper<MainSite> mainSiteQueryWrapper = new QueryWrapper<MainSite>();
				String mainUrl1 = internalSite.getMainUrl();
				mainSiteQueryWrapper.eq("main_site_url",mainUrl1);
				List<MainSite> mainSiteList = iMainSiteService.list(mainSiteQueryWrapper);
				if(mainSiteList.size() >= 1){
					MainSite mainSite = mainSiteList.get(0);
					errorDetection.setMainSiteId(mainSite.getId());
					errorDetection.setMainSiteName(mainSite.getMainSiteName());
					errorDetection.setMainSiteUrl(mainSite.getMainSiteUrl());
				}
				errorDetection.setErrorUrl(internalSite.getUrl());
				errorDetection.setErrorUrlType(internalSite.getTypeUrl());
				errorDetection.setErrorUrlState(internalSite.getStateUrl());
				//设置引用页数
				QueryWrapper<ExternalInternalSite> siteQueryWrapper = new QueryWrapper<ExternalInternalSite>();
				siteQueryWrapper.eq("url",internalSite.getUrl());
				long countSiteQuery = externalInternalSiteService.count(siteQueryWrapper);
				errorDetection.setNumberApplicationPages(Integer.parseInt(String.valueOf(countSiteQuery)));

				QueryWrapper<LinkChainErrorDetection> linkChainErrorDetectionQueryWrapper = new QueryWrapper<LinkChainErrorDetection>();
				linkChainErrorDetectionQueryWrapper.eq("id",internalSite.getId());
				Page<LinkChainErrorDetection> pageListS = new Page<LinkChainErrorDetection>(1, 1);
				Page<LinkChainErrorDetection> page1 = linkChainErrorDetectionService.page(pageListS,linkChainErrorDetectionQueryWrapper);
				List<LinkChainErrorDetection> chainErrorDetections = page1.getRecords();
				LinkChainErrorDetection chainDetection = null;
				if(chainErrorDetections.size() >=1){
					chainDetection = chainErrorDetections.get(0);
				}
				if(!org.springframework.util.ObjectUtils.isEmpty(chainDetection)){
					errorDetection.setUpdateTime(chainDetection.getUpdateTime());
					Integer numberScans = chainDetection.getNumberScans();
					numberScans = numberScans +1;
					errorDetection.setNumberScans(numberScans);
				}else{
					errorDetection.setNumberScans(1);
				}
				errorDetection.setIsRevise("2");
				errorDetection.setIsIgnore("2");
				errorDetection.setCheckState("2");
				System.out.println(errorDetection);
				errorDetection.setTenantId(internalSite.getTenantId());
				linkChainErrorDetectionService.saveOrUpdate(errorDetection);
				//记录日志信息
				LinkChainErrorLog linkChainErrorLog = new LinkChainErrorLog();
				linkChainErrorLog.setId(IdWorker.getIdStr());
				linkChainErrorLog.setCreateBy(errorDetection.getCreateBy());
				linkChainErrorLog.setCreateTime(errorDetection.getCreateTime());
				linkChainErrorLog.setUpdateBy(errorDetection.getUpdateBy());
				linkChainErrorLog.setUpdateTime(errorDetection.getUpdateTime());
				linkChainErrorLog.setErrorDetectionId(errorDetection.getId());
				linkChainErrorLog.setMainSiteId(errorDetection.getMainSiteId());
				linkChainErrorLog.setMainSiteName(errorDetection.getMainSiteName());
				linkChainErrorLog.setMainSiteUrl(errorDetection.getMainSiteUrl());
				linkChainErrorLog.setErrorUrl(errorDetection.getErrorUrl());
				linkChainErrorLog.setErrorUrlType(errorDetection.getErrorUrlType());
				linkChainErrorLog.setErrorUrlState(errorDetection.getErrorUrlState());
				linkChainErrorLog.setNumberApplicationPages(errorDetection.getNumberApplicationPages());
				linkChainErrorLog.setNumberScans(errorDetection.getNumberScans());
				linkChainErrorLog.setNumberScans(errorDetection.getNumberScans());
				linkChainErrorLog.setIsRevise(errorDetection.getIsRevise());
				linkChainErrorLog.setIsIgnore(errorDetection.getIsIgnore());
				linkChainErrorLog.setCheckTime(errorDetection.getCheckTime());
				linkChainErrorLog.setCheckState(errorDetection.getCheckState());
				linkChainErrorLog.setCheckMessage(errorDetection.getCheckMessage());
				linkChainErrorLog.setTenantId(internalSite.getTenantId());
				boolean save = iLinkChainErrorLogService.save(linkChainErrorLog);

			}
		}
	}
	public void multithreading(Integer threadNumber,MainSite mainSite,String TenantId) throws InterruptedException {
		TenantContext.setTenant(TenantId);
		long countExternalInternalSite = externalInternalSiteService.countSourceLinkError(mainSite.getMainSiteUrl());
		this.ThreadpageNum = (int)Math.ceil((double)countExternalInternalSite/threadNumber);
		log.info(countExternalInternalSite+"");
		log.info("ThreadpageNum========"+ThreadpageNum+"");
		List<Map<Integer,Integer>> integerList = new ArrayList<Map<Integer,Integer>>();
		for (Integer i = 0; i < threadNumber; i++) {
			Map<Integer,Integer> hashMap = new HashMap<Integer,Integer>();
			Integer index =  ThreadpageNum * i;
			if(index == 0){
				index = 1;
			}
			hashMap.put(index,ThreadpageNum * (i+1));
			integerList.add(hashMap);
		}
		for (Map<Integer, Integer> integerIntegerMap : integerList) {
			Iterator<Map.Entry<Integer, Integer>> iterator = integerIntegerMap.entrySet().iterator();
			Integer threadIndex = 1;
			Vector<Thread> threadVector = new Vector<Thread>();
			while(iterator.hasNext()){
				Map.Entry<Integer,Integer> entry = iterator.next();
				Integer keyStart = entry.getKey();
				Integer valueEnd = entry.getValue();
				Integer finalThreadIndex = threadIndex;
				Thread thread = new Thread(){
					@Override
					public void run() {
						Integer count =  valueEnd - keyStart;
						Integer pageSize = 100;
						Integer pageNum = (int)Math.ceil((double)count/pageSize);
						for (Integer i = keyStart; i <= valueEnd; i+=pageSize) {
							System.out.println("========================");
							System.out.println(keyStart);
							System.out.println(valueEnd);
							System.out.println("========================");
							TenantContext.setTenant(TenantId);
							List<ExternalInternalSite> externalInternalSiteList =  externalInternalSiteService.listPageLinkChainError(i,pageSize);
							for (ExternalInternalSite internalSite : externalInternalSiteList) {
								System.out.println(internalSite);
								String url = internalSite.getUrl();
								//爬取页面
								Document document = null;
								try {
									document = Jsoup.parse(new URL(url), 10000);
								}catch (Exception e){

								}
								if(!ObjectUtils.isEmpty(document) ){
									continue;
								}
								LinkChainErrorDetection errorDetection = new LinkChainErrorDetection();
								errorDetection.setId(DigestUtils.md5DigestAsHex(internalSite.getUrl().getBytes()));
								errorDetection.setCreateBy(internalSite.getMainUrl());
								errorDetection.setCreateTime(new Date());
								errorDetection.setUpdateBy(internalSite.getMainUrl());
								errorDetection.setUpdateTime(new Date());
								QueryWrapper<MainSite> mainSiteQueryWrapper = new QueryWrapper<MainSite>();
								String mainUrl1 = internalSite.getMainUrl();
								mainSiteQueryWrapper.eq("main_site_url",mainUrl1);
								List<MainSite> mainSiteList = iMainSiteService.list(mainSiteQueryWrapper);
								if(mainSiteList.size() >= 1){
									MainSite mainSite = mainSiteList.get(0);
									errorDetection.setMainSiteId(mainSite.getId());
									errorDetection.setMainSiteName(mainSite.getMainSiteName());
									errorDetection.setMainSiteUrl(mainSite.getMainSiteUrl());
								}
								errorDetection.setErrorUrl(internalSite.getUrl());
								errorDetection.setErrorUrlType(internalSite.getTypeUrl());
								errorDetection.setErrorUrlState(internalSite.getStateUrl());
								//设置引用页数
								QueryWrapper<ExternalInternalSite> siteQueryWrapper = new QueryWrapper<ExternalInternalSite>();
								siteQueryWrapper.eq("url",internalSite.getUrl());
								long countSiteQuery = externalInternalSiteService.count(siteQueryWrapper);
								errorDetection.setNumberApplicationPages(Integer.parseInt(String.valueOf(countSiteQuery)));

								QueryWrapper<LinkChainErrorDetection> linkChainErrorDetectionQueryWrapper = new QueryWrapper<LinkChainErrorDetection>();
								linkChainErrorDetectionQueryWrapper.eq("id",internalSite.getId());
								Page<LinkChainErrorDetection> pageListS = new Page<LinkChainErrorDetection>(1, 1);
								Page<LinkChainErrorDetection> page1 = linkChainErrorDetectionService.page(pageListS,linkChainErrorDetectionQueryWrapper);
								List<LinkChainErrorDetection> chainErrorDetections = page1.getRecords();
								LinkChainErrorDetection chainDetection = null;
								if(chainErrorDetections.size() >=1){
									chainDetection = chainErrorDetections.get(0);
								}
								if(!org.springframework.util.ObjectUtils.isEmpty(chainDetection)){
									errorDetection.setUpdateTime(chainDetection.getUpdateTime());
									Integer numberScans = chainDetection.getNumberScans();
									numberScans = numberScans +1;
									errorDetection.setNumberScans(numberScans);
								}else{
									errorDetection.setNumberScans(1);
								}
								errorDetection.setIsRevise("2");
								errorDetection.setIsIgnore("2");
								errorDetection.setCheckState("2");
								System.out.println(errorDetection);
								errorDetection.setTenantId(internalSite.getTenantId());
								linkChainErrorDetectionService.saveOrUpdate(errorDetection);
								//记录日志信息
								LinkChainErrorLog linkChainErrorLog = new LinkChainErrorLog();
								linkChainErrorLog.setId(IdWorker.getIdStr());
								linkChainErrorLog.setCreateBy(errorDetection.getCreateBy());
								linkChainErrorLog.setCreateTime(errorDetection.getCreateTime());
								linkChainErrorLog.setUpdateBy(errorDetection.getUpdateBy());
								linkChainErrorLog.setUpdateTime(errorDetection.getUpdateTime());
								linkChainErrorLog.setErrorDetectionId(errorDetection.getId());
								linkChainErrorLog.setMainSiteId(errorDetection.getMainSiteId());
								linkChainErrorLog.setMainSiteName(errorDetection.getMainSiteName());
								linkChainErrorLog.setMainSiteUrl(errorDetection.getMainSiteUrl());
								linkChainErrorLog.setErrorUrl(errorDetection.getErrorUrl());
								linkChainErrorLog.setErrorUrlType(errorDetection.getErrorUrlType());
								linkChainErrorLog.setErrorUrlState(errorDetection.getErrorUrlState());
								linkChainErrorLog.setNumberApplicationPages(errorDetection.getNumberApplicationPages());
								linkChainErrorLog.setNumberScans(errorDetection.getNumberScans());
								linkChainErrorLog.setNumberScans(errorDetection.getNumberScans());
								linkChainErrorLog.setIsRevise(errorDetection.getIsRevise());
								linkChainErrorLog.setIsIgnore(errorDetection.getIsIgnore());
								linkChainErrorLog.setCheckTime(errorDetection.getCheckTime());
								linkChainErrorLog.setCheckState(errorDetection.getCheckState());
								linkChainErrorLog.setCheckMessage(errorDetection.getCheckMessage());
								linkChainErrorLog.setTenantId(internalSite.getTenantId());
								boolean save = iLinkChainErrorLogService.save(linkChainErrorLog);
							}
						}
					}
				};
				threadVector.add(thread);
				threadIndex++;
			}
			for (Thread thread : threadVector) {
				thread.join();
			}
		}
	}
}
