package net.northking.cctp.daemon.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import net.northking.cctp.daemon.config.DaemonProperties;
import net.northking.cctp.daemon.config.EngineProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

public class RobotProcess  extends AppLifecycle{

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

    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 配置参数
     */
    private final DaemonProperties daemonProperties;
    private final EngineProperties engineProperties;

    private final RestTemplate restTemplate;

    private final DaemonService daemonService;

    private String PID;


    public RobotProcess(DaemonProperties daemonProperties, RestTemplate restTemplate, DaemonService daemonService)
    {
        this.daemonProperties = daemonProperties;
        this.engineProperties = daemonProperties.getEngine();
        this.restTemplate = restTemplate;
        this.daemonService = daemonService;
    }

    @Override
    public String getPid() {
        return null;
    }

    @Override
    public boolean isStarted() {
        return false;
    }


    @Override
    public void start()
    {
        if(daemonService.startCheck()){
            startOnWindows();
        }else{
            logger.info("robot daemon =============== 等待更新暂不启动");
        }
    }

    private void startOnWindows() {
        try {
            String path = System.getProperty("user.dir")+"/../engine/robot/";
            Process process = Runtime.getRuntime().exec("cmd /c start /b "+path+"start.bat");
            Thread.sleep(2000);
            Process killcmd = Runtime.getRuntime().exec("cmd /c start /b "+path+"startKill.bat");
        } catch (Exception e) {
            logger.error("",e);
            logger.info("robot daemon ======机器人启动失败");
        }
        logger.info("robot daemon ======机器人启动成功");
    }


    @Override
    public void stop() {

    }

    @Override
    public void shutdown() {
        String path = System.getProperty("user.dir")+"/../engine/robot/stop.bat";
        try {
            Process process = Runtime.getRuntime().exec("cmd /c start /b "+path);
        } catch (Exception e) {
            logger.error("",e);
            logger.info("robot daemon ======机器人关闭失败");
        }
        logger.info("robot daemon =======机器人关闭成功");
    }

    @Override
    public void restart() {
        try {
            shutdown();
            Thread.sleep(2000);
            start();
        }catch (Exception e){
            logger.error("",e);
            logger.info("robot daemon ========机器人重启失败");
        }
    }
    @Override
    public boolean alive() {
        String path = "http://localhost:5590/service/";
        boolean status = false;
        int num=0;
        while (!status && num<5){
            long timeA = System.currentTimeMillis();
            try {
                Map<String, String> uriVariables = new HashMap<>();
                uriVariables.put("cmd","Ping");
                uriVariables.put("seqId","收到请回答,over");
                ResponseEntity<String> result = restTemplate.postForEntity(path, uriVariables,String.class);
                if(HttpStatus.OK.equals(result.getStatusCode())){
                    status=true;//请求成功
                }else{
                    num++;
                    Thread.sleep(1000);//如果失败则每秒重试一此
                }
                logger.debug("收到机器人信息报文：{}", result.getBody());
            }catch (Exception e){
                num++;
                try {
                    Thread.sleep(1000);//如果报错失败则每秒重试一此
                } catch (Exception e1) {
                    logger.error("迷",e1);
                }
                logger.error("机器人请求失败",e);
            }
            long timeB = System.currentTimeMillis();
            logger.info("机器人心跳请求第{}次，耗时：{}",num,timeB-timeA);
        }
        return status;
    }
}
