<?php
namespace app\crm\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;

class Server extends Command
{
    protected function configure()
    {
        $this->setName('server')->setDescription('Suxuan system service');
    }
    
    protected function execute(Input $input, Output $output)
    {

        /**
         * 在以下的processList 数组内配置需要执行的方法，此方法名称，放入crmservice.php内进行判断执行
         *    $ProcessList = array(
         *        ['method'=>'test'],
         *        ['method'=>'test2'],
         *    );
         * 
         */
        $processList = config('server_list');
        if(empty($processList)){
            $processList = array(
                'runlogs',
                'runfp',
                'rundfp',
                'runimport',
                'runsocket',
                'wxmessage',
            );
        }
        $cacheNoticeKey = 'sxmonitor_serializelist';
        if(cache('?'.$cacheNoticeKey)){
            $cacheNotice = cache($cacheNoticeKey);
            if(is_string($cacheNotice)){
                $cacheNotice = json_decode($cacheNotice,true);
                if(null === $cacheNotice){
                    $cacheNotice = [];
                }
            }
            $cacheNotice['last_active'] =date('Y-m-d H:i:s');
        }else{
            $cacheNotice = [];
            $cacheNotice['last_active'] =date('Y-m-d H:i:s');
        }
        if($cacheNotice['service_list'] && is_array($cacheNotice['service_list'])){
            foreach ($cacheNotice['service_list'] as $key => $value) {
                # code...
                if(!in_array($key, $processList)){
                    unset($cacheNotice['service_list'][$key]);
                }
            }
        }

        $restartCacheKey = 'service_control_sign';
        $restartSign = cache($restartCacheKey);
        if(is_string($restartSign)){
            $restartSign = json_decode($restartSign,true);
        }
        $restartArray = [];
        if(!empty($restartSign)){
            $signRewrite = 0;
            foreach ($restartSign as $key => $value) {
                if(in_array($key, $processList) && $value['sign'] == 'restart' && $value['status'] != 1){
                    $processId = $this->checkProcess($key);
                    if($processId){
                        $this->killProcess($processId);
                        $restartArray[] = $key;
                    }
                    $restartSign[$key]['status'] = 1;
                    $signRewrite = 1;
                }
            }
            if($signRewrite){
                cache($restartCacheKey,$restartSign);
            }
        }
        foreach ($processList as $v) {
            $pid = $this->checkProcess($v);
            if(!$pid){
                $this->startProcess($v);
                if(in_array($v, $restartArray)){
                    $cacheNotice['service_list'][$v] = ['restart_count'=>0,'last_restart'=>date('Y-m-d H:i:s')];
                }else{
                    $lastCount = (int)$cacheNotice['service_list'][$v]['restart_count'];
                    $lastCount++;
                    $cacheNotice['service_list'][$v] = [
                            'restart_count'=>$lastCount,
                            'last_restart'=>date('Y-m-d H:i:s')
                        ];
                }
            }else{
                if(!isset($cacheNotice['service_list'][$v])){
                    $cacheNotice['service_list'][$v] = [
                            'restart_count'=>0,
                            'last_restart'=>date('Y-m-d H:i:s')
                        ];
                }
                
                
            }
        }
        cache($cacheNoticeKey,$cacheNotice);
    }
    function checkProcess($runName){
        if(!$runName){
            return false;
        }
        $processName = $_SERVER['argv'][0]." ".$runName;
        $checkCmd = "ps ax |grep '{$processName}' |grep -v grep";
        if(!function_exists("exec")){
            echo "Error:Can't use exec with php cli model.";
            die;
        }
        $res = exec($checkCmd,$op,$status);
        if($res !== false){
            if(empty(trim($res))){
                return false;
            }else{
                $result = explode(" ",trim($op[0]));
                return $result[0];
            }
        }else{
            echo "Error:Can't check process.Please check your right.";
            die;
        }
    }
    function killProcess($processId){
        if(!$processId){
            return false;
        }
        $cmd = "kill ".$processId;
        return exec($cmd);
    }

    function startProcess($runName){
        //启动命令，最后传个根目录是为了shell可以以绝对路径保存日志
        $processName = ROOT_PATH.'server.sh '.$runName.' start '.ROOT_PATH;
        return pclose(popen($processName,'r'));
    }

}