package net.teaman.business.ScheduledTask;


import net.teaman.business.appDetection.entity.ManagerApplicationEntity;
import net.teaman.business.tomcatDetection.entity.HostCpuResultEntity;
import net.teaman.business.tomcatDetection.entity.ManagerTomcatEntity;
import net.teaman.business.tomcatDetection.entity.TomcatResultEntity;
import net.teaman.business.tomcatDetection.entity.TomcatSessionResultEntity;
import net.teaman.utils.HttpClientUtils;
import net.teaman.utils.UUIDUtil;
import net.teaman.utils.ssh2.SSHUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * ①通过@Async 注解表明该方法是个异步方法,如果注解在类级别,则表明该类所有的
 * 方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor 作为TaskExecutor

 */
@Service
public class AsyncTaskService {


    /**
     * 检查应用超时情况
     * @param res
     */
    @Async
    public void executeAsyncTask(ManagerApplicationEntity res) {
        try{
            String url = res.getUrl();
            int type = res.getType();
            int timeOut = res.getTimeOut();
            int current = res.getCorrectTimeOut();
            int resCode = 0;
            if(type==1) {
               resCode = HttpClientUtils.post(url, null, 1000, timeOut, 10000);
            }else{
               resCode = HttpClientUtils.get(url, null, 1000, timeOut, 10000);
            }
            res.setResult(resCode%1000+"");
            res.setTime(resCode/1000+"");
            if((resCode%1000)==200&&(resCode/1000<=current)){
                res.setColor(1);
            }else if((resCode%1000)==200&&(resCode/1000<=timeOut)){
                res.setColor(2);
            }else{
                res.setColor(3);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        finally{
            res.setStatus(true);
        }

    }

    /**
     * 检测tomcat运行状况
     * @param res
     * @param type 1:临时查看不记录
     */
    @Async
    public void executeAsyncTaskTwo(ManagerTomcatEntity res,int type) {
        try {

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        TomcatResultEntity resultEntity = new TomcatResultEntity();
        resultEntity.setId(UUIDUtil.generate());
        resultEntity.setTomcatId(res.getId());
        resultEntity.setIp(res.getIp());
        resultEntity.setApplication(res.getApplication());
        Calendar cal = Calendar.getInstance(TimeZone.getDefault());
        resultEntity.setTime(System.currentTimeMillis()/1000*1000+cal.getTimeZone().getRawOffset());
        resultEntity.setTimeText(dateFormat.format(new Date()));
        String auth = res.getTomcatPassword();
        auth = "Basic "+auth;
        String result = HttpClientUtils.get(res.getUrl(),auth);
        Document doc = null;
        if(result==null){
            resultEntity.setResult("连接失败,无法建立连接或账户密码错误。");
        }else{
            resultEntity.setResult("200");
            doc = Jsoup.parse(result);
            //JVM 和线程状态获取
            Elements jvm = doc.select("p");
            int count = 0;
            for(Element t:jvm){
                count++;
                if(t.text().contains("Free memory:")){
                    Pattern pattern = Pattern.compile("\\d+\\.?\\d");
                    Matcher matcher = pattern.matcher(t.text());
                    int flag = 0;
                    while (matcher.find()){
                        flag++;
                        if(flag==1){
                            resultEntity.setJavaFree(matcher.group());
                        }
                        if(flag==2){
                            resultEntity.setJavaTotal(matcher.group());
                        }
                        if(flag==3){
                            resultEntity.setJavaMax(matcher.group());
                            double useMb = Double.parseDouble(resultEntity.getJavaTotal())-Double.parseDouble(resultEntity.getJavaFree());
                            double use = useMb/Double.parseDouble(matcher.group());
                            BigDecimal bg = new BigDecimal(use);
                            double f1 = bg.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
                            resultEntity.setPsJVM(f1);
                        }

                    }
                }
                if(count==4){
                    resultEntity.setThreads(t.text());
                    Pattern pattern = Pattern.compile("Current thread count: (\\d+)");
                    Matcher matcher = pattern.matcher(t.text());
                    while (matcher.find()){
                        String threadCount = matcher.group().replace("Current thread count: ","");
                        resultEntity.setThreadCount(Integer.parseInt(threadCount));
                    }
                }
            }

            Elements tbody = doc.select("tbody");
            for(Element t:tbody){
                if(t.text().contains("PS Eden Space")){
                    Elements trs = t.select("tr");
                    for(Element tr:trs){
                        if(tr.text().contains("PS Eden Space")){
                            resultEntity.setPsEdenSpace(tr.text());
                        }
                        if(tr.text().contains("PS Old Gen")){
                            resultEntity.setPsOldGen(tr.text());
                        }
                        if(tr.text().contains("PS Survivor Space")){
                            resultEntity.setPsSurvivorSpace(tr.text());
                        }
                        if(tr.text().contains("Code Cache")){
                            resultEntity.setCodeCache(tr.text());
                        }
                        if(tr.text().contains("Compressed Class Space")){
                            resultEntity.setCompressedClassSpace(tr.text());
                        }
                        if(tr.text().contains("Metaspace")){
                            resultEntity.setPsMetaspace(tr.text());
                        }
                    }
                }
            }

        }
        res.setTomcatResultEntity(resultEntity);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            res.setMainStatus(true);
        }

    }

    /**
     * 检测tomcat Session数量
     * @param res
     */
    @Async
    public void executeAsyncTaskThree(ManagerTomcatEntity res) {
        try {

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            TomcatSessionResultEntity resultEntity = new TomcatSessionResultEntity();
            resultEntity.setId(UUIDUtil.generate());
            resultEntity.setTomcatId(res.getId());
            resultEntity.setIp(res.getIp());
            resultEntity.setApplication(res.getApplication());
            Calendar cal = Calendar.getInstance(TimeZone.getDefault());
            resultEntity.setTime(System.currentTimeMillis()/1000*1000+cal.getTimeZone().getRawOffset());
            resultEntity.setTimeText(dateFormat.format(new Date()));
            String auth = res.getTomcatPassword();
            auth = "Basic "+auth;
            String result = HttpClientUtils.get(res.getManagerUrl(),auth);
            Document doc = null;
            if(result==null){
                resultEntity.setResult("连接失败,无法建立连接或账户密码错误。");
            }else{
                resultEntity.setResult("200");
                doc = Jsoup.parse(result);
                //JVM 和线程状态获取
                Elements a = doc.select("a");
                int count = 0;
                for(Element t:a) {
                    if(t.text()!=null&&!"".equals(t.text())) {
                        Pattern pattern = Pattern.compile("[0-9]*");
                        Matcher matcher = pattern.matcher(t.text());
                        if (matcher.matches()) {
                            count = count + Integer.parseInt(matcher.group());
                        }
                    }
                }
                resultEntity.setSessionCount(count);
            }
            res.setTomcatSessionResultEntity(resultEntity);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            res.setSessionStatus(true);
        }

    }

    /**
     * 检测主机cpu使用状态
     * @param res
     */
    @Async
    public void executeAsyncTaskFour(ManagerTomcatEntity res){
       try {

           SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
           HostCpuResultEntity cpuInfo = new HostCpuResultEntity();
           cpuInfo.setId(UUIDUtil.generate());
           cpuInfo.setTomcatId(res.getId());
           cpuInfo.setIp(res.getIp());
           Calendar cal = Calendar.getInstance(TimeZone.getDefault());
           cpuInfo.setTime(System.currentTimeMillis() / 1000 * 1000 + cal.getTimeZone().getRawOffset());
           cpuInfo.setTimeText(dateFormat.format(new Date()));
           String userName = res.getHostUser();
           String password = res.getHostPassword();
           String ip = res.getIp();
           String result = SSHUtil.getCpuInfo(userName, password, ip);
           if (result == null) {
               cpuInfo.setResult("ssh连接失败!");
           } else if ("错误:该主机下含有多个tomcat应用!".equals(result)) {
               cpuInfo.setResult("错误:该主机下含有多个tomcat应用!");
           } else {
               cpuInfo.setResult("200");
               cpuInfo.setCpuInfo(Double.parseDouble(result));
           }
           res.setHostCpuResultEntity(cpuInfo);
       }catch (Exception e){
           e.printStackTrace();
       }finally {
           res.setCpuStatus(true);
       }
    }

}