package net.northking.cctp.se.lifecycle;

import com.fasterxml.jackson.databind.ObjectMapper;
import net.northking.cctp.se.lifecycle.entity.AppLifecycle;
import net.northking.cctp.se.lifecycle.win.TaskKill;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

@Component
public class DaemonProcess extends AppLifecycle {

    private static final Logger logger = LoggerFactory.getLogger(DaemonProcess.class);

    private ObjectMapper objectMapper = new ObjectMapper();

    private String PID;
    private final RestTemplate restTemplate;

    public DaemonProcess(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Override
    public boolean isStarted()
    {
        String pid = getPid();

        if (pid == null || "".equals(pid.trim()))
        {
            return false;
        }
        return findProcessByPid(pid).size() > 0;
    }

    @Override
    public void start()
    {
        try{
            String path = System.getProperty("user.dir")+"/../daemon/start.bat";
            String command = "cmd /c start "+path;
            logger.info("启动【脚本引擎】，执行命令：{}", command);
            Process process = Runtime.getRuntime().exec(command);
            process.waitFor();
        }catch (Exception e){
            logger.error("启动守护进程发生异常！", e);
        }
    }

    @Override
    public void stop()
    {
        shutdown();
    }


    @Override
    public void restart()
    {
        stop();
        start();
    }

    private int aliveCount = 0;

    private boolean count() {
        boolean flag = aliveCount % 15 == 0;
        if (flag) {
            aliveCount = 0;
        }
        return flag;
    }

    @Override
    public boolean alive()
    {
        String infoUrl = "http://localhost:9528/v1/info";
        Map<String, String> uriVariables = new HashMap<>();

        try
        {
            boolean flag = count();
            if (flag) {
                logger.debug("获取脚本引擎信息，请求接口：HTTP GET {}", infoUrl);
            }
            String responseBody = restTemplate.getForObject(infoUrl, String.class, uriVariables);
            if (flag) {
                logger.debug("收到脚本引擎信息报文：{}", responseBody);
                logger.info("守护进程 ,PID={} 运行正常。",PID);
            }
            aliveCount++;
        } catch (Exception ex)
        {
            logger.info("脚本引擎信息获取失败: "+ ex.getMessage());
            return false;
        }
        return true;
    }

    @Override
    public String getPid()
    {
        String pidFile =  System.getProperty("user.dir")+"/../daemon/daemon.pid";
        try (Scanner sc = new Scanner(new FileReader(pidFile)))
        {
            while (sc.hasNextLine())
            {  //按行读取字符串
                PID = sc.nextLine();
            }
        } catch (FileNotFoundException e)
        {
            logger.error("守护进程的PID文件不存在！" + e.getMessage());
        }
        if (count()) {
            logger.debug("获取守护进程的进程号：{}", PID);
        }
        return PID;
    }

    @Override
    public void shutdown()
    {
        TaskKill taskKill = new TaskKill();
        taskKill.force(true);
        String pid = getPid();
        if (pid != null && pid.trim().length() > 0)
        {
            taskKill.pid(pid);
            taskKill.execute();
            logger.debug("关闭进程，根据进程号杀掉进程：PID={}", pid);
        }
    }
}
