package net.northking.cctp.upperComputer.webSocket.thread;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.northking.cctp.upperComputer.utils.ProcessCmdUtils;
import net.northking.cctp.upperComputer.utils.SessionUtils;
import net.northking.cctp.upperComputer.webSocket.entity.CmdRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.Session;
import java.io.*;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author: WuJinQuan
 * @date:2021-09-08 15:14
 **/
public class IosPerfThread extends Thread {
    private final static Logger logger = LoggerFactory.getLogger(IosPerfThread.class);
    private String serial;
    private String packageName;
    private Session session;
    private CmdRequest cmdRequest;
    private Process process;
    private IosPerfDataRead iosPerfDataRead;
    private String[] perfCmd;

    public IosPerfThread(Session session,CmdRequest cmdRequest){
        this.session = session;
        this.cmdRequest = cmdRequest;
    }

    public void initData(String serial, String packageName) {
        setName("IosPerfThread-"+serial);
        this.serial = serial;//设备号
        this.packageName = packageName;//包名
        this.perfCmd = new String[]{"tidevice", "-u", serial, "perf", "-B",packageName};
        startApp();
    }

    public boolean isWindows() {
        return System.getProperties().getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1;
    }

    @Override
    public void run() {
        long startTime = System.currentTimeMillis();
        InputStreamReader ir = null;
        logger.info("开始获取性能时间：{}", LocalDateTime.now());
        try {
            process = ProcessCmdUtils.execCmd(Arrays.asList(perfCmd));
            long exeShellTime = System.currentTimeMillis();
            ir = new InputStreamReader(process.getInputStream(),"UTF-8");
            long getInputStreamTime = System.currentTimeMillis();
            BufferedReader br = new BufferedReader(ir);
            long bufferedReaderTime = System.currentTimeMillis();
            logger.debug("输出信息：{}",br.readLine());
            iosPerfDataRead = new IosPerfDataRead();
            iosPerfDataRead.init(br);
            iosPerfDataRead.run();
            long initSocketStreamTime = System.currentTimeMillis();
            Thread.sleep(2000);
            iosPerfDataRead.stopRead();
            process.destroyForcibly();
        } catch (Exception e) {
            logger.error("读取ios性能异常：",e);
            e.printStackTrace();
        }
    }

    private void startApp() {
        Process proc = null;
        String[] launchAppCmd = new String[]{"tidevice", "-u", serial, "launch", packageName};
        ProcessBuilder builder = new ProcessBuilder(Arrays.asList(launchAppCmd)).redirectErrorStream(true);
        try {
            proc = builder.start();
            if (proc.waitFor() != 0) {
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void stopThread(){
        if (null != iosPerfDataRead) {
            iosPerfDataRead.stopRead();
        }
        if (null != process) {
            process.destroy();
        }
    }

    class IosPerfDataRead {
        private boolean b = false;
        private BufferedReader reader;

        public void init(BufferedReader reader) {
            b = true;
            this.reader = reader;
        }

        public void stopRead() {
            b = false;
        }

        public void run() {
            //启动线程，负责读标准输出流
            JSONObject jsonObject;
            Double d;
            String upFlow;
            String downFlow;
            Map<String, Object> perfMap = new HashMap<>(8);
            try {
                String line1;
                while (b) {
                    while ((line1 = reader.readLine()) != null) {
                        if (line1 != null) {
                            if (line1.indexOf(" ") > 0) {
                                String key = line1.substring(0, line1.indexOf(" "));
                                if ("cpu".equals(key) || "memory".equals(key) || "fps".equals(key) || "network".equals(key)) {
                                    String value = line1.replace(key + " ", "");
                                    try {
                                        jsonObject = JSON.parseObject(value);
                                    } catch (Exception e) {
                                        logger.error("Json转换失败", e);
                                        continue;
                                    }
                                    switch (key) {
                                        case "cpu":
                                            value = jsonObject.getString("value");
                                            if (value == null) {
                                                d = 0.0;
                                            } else {
                                                d = Double.valueOf(value);
                                            }
                                            value = String.format("%.2f", d);
                                            perfMap.put("cpu", value);
                                            break;
                                        case "memory":
                                            value = jsonObject.getString("value");
                                            if (value == null) {
                                                d = 0.0;
                                            } else {
                                                d = Double.valueOf(value);
                                            }
                                            value = String.format("%.2f", d);
                                            perfMap.put("memory", value);
                                            break;
                                        case "fps":
                                            value = jsonObject.getString("fps");
                                            if (value == null) {
                                                value = "0";
                                            }
                                            perfMap.put("fps", value);
                                            break;
                                        case "network":
                                            upFlow = jsonObject.getString("upFlow");
                                            if (upFlow == null) {
                                                d = 0.0;
                                            } else {
                                                d = Double.valueOf(upFlow);
                                            }
                                            upFlow = String.format("%.2f", d);
                                            perfMap.put("upFlow", upFlow);
                                            downFlow = jsonObject.getString("downFlow");
                                            if (downFlow == null) {
                                                d = 0.0;
                                            } else {
                                                d = Double.valueOf(downFlow);
                                            }
                                            downFlow = String.format("%.2f", d);
                                            perfMap.put("downFlow", downFlow);
                                            break;
                                        default:
                                            break;
                                    }
                                    SessionUtils.sendContinuousData(session, cmdRequest, perfMap, "获取实时性能数据成功");
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("获取性能数据异常", e);
            } finally {
                try {
                    reader.close();
                } catch (IOException e) {
                    logger.error("reader关闭失败，e",e);
                }
            }
        }
    }
}
