<?php

namespace web\admin\autotask;

class task {
    //http://xx.local.ciy.cn/ajax/admin/autotask/task.run
    //php D:/Dreams/ciy/c5_dao/web/admin/autotask/run.php
    public static function json_run() {
        self::main();
        echo '全部执行完成';
        return 'html';
    }
    public static function main() {
        global $db;
        while (true) {
            $csql = new \ciy\sql('zc_autotask');
            $csql->where('autotaskstatus<', 90)->where('nexttimes<=', tostamp());
            $systemrow = $db->getone($csql);
            if (!is_array($systemrow))
                break;
            self::run($db, $systemrow);
        }
    }
    public static function json_main() {
        global $db;
        set_time_limit(0);
        if (isset($_SERVER['HTTP_HOST']))
            ob_end_clean();
        $db = new \ciy\db();
        $rsuser = verifyuser();
        if ($rsuser == null)
            return clog('您未登录');
        if (nopower($db, $rsuser['id'], 'p602r'))
            return clog('您未被授权操作');
        echo '<!DOCTYPE html> <html><head>';
        echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
        echo '<title>AutoTask Running</title>';
        echo '</head><body>';
        //status:   2等待执行，3执行中，9禁止
        $runid = getint('runid');
        if ($runid == 0) {
            clog('runid参数错误');
        }
        $csql = new \ciy\sql('zc_autotask');
        $csql->where('id', $runid);
        $taskrow = $db->getone($csql);
        if (!is_array($taskrow))
            return clog('任务ID不存在:' . $runid);
        $taskrow['autotaskstatus'] = 20;
        $runtaskid = self::run($db, $taskrow);
        $csql = new \ciy\sql('zc_autotsk_run');
        $csql->where('id', $runtaskid);
        $tskrunrow = $db->getone($csql);
        if (!is_array($tskrunrow))
            return clog('任务运行记录不存在:' . $runtaskid);
        $csql = new \ciy\sql('zc_autotsk_log');
        $csql->where('runtaskid', $runtaskid);
        $csql->column('addtimes,msg');
        $tsklogrows = $db->get($csql);
        $html = '';
        $html .= '<table border="1" style="border-collapse:collapse;font-size:0.8em;" cellpadding="5px">';
        $html .= '<tr><td>任务名称</td><td>' . $taskrow['name'] . '</td></tr>';
        $html .= '<tr><td>入口函数</td><td>' . $taskrow['runfunc'] . '</td></tr>';
        $html .= '<tr><td>执行参数</td><td>' . $taskrow['runparam'] . '</td></tr>';
        $html .= '<tr><td>执行时长</td><td>' . $tskrunrow['runsec'] . 's</td></tr>';
        $html .= '<tr><td>任务简报</td><td>' . $tskrunrow['msg'] . '</td></tr>';
        $html .= '</table>';
        if (count($tsklogrows) > 0) {
            $html .= '<br/><table border="1" style="border-collapse:collapse;font-size:0.8em;" cellpadding="5px">';
            $html .= '<tr><td>时间</td><td>数据</td></tr>';
            foreach ($tsklogrows as $row) {
                $html .= '<tr><td>' . date('Y-m-d H:i:s', $row['addtimes']) . '</td><td>' . $row['msg'] . '</td></tr>';
            }
            $html .= '</table>';
        } else {
            $html .= '无日志记录';
        }
        echo $html;
        echo '</body></html>';
    }
    public static function outputhtml($html) {
    }
    // exit
    static function run($db, $taskrow) {
        if (empty($taskrow['runfunc']) || $taskrow['runfunc'][0] == '_')
            return;
        $sysid = $taskrow['id'];
        $nexttimes = $taskrow['nexttimes'];
        $runcycle = toint($taskrow['runcycle']);
        while (true) {
            if ($nexttimes > tostamp())
                break;
            if ($runcycle < 0)
                $nexttimes = fixmonth(-$runcycle, $nexttimes);
            else
                $nexttimes += $runcycle;
        }
        $updata = array();
        if ($taskrow['autotaskstatus'] == 30) {
            $runningmsg = '任务执行中，本次跳过';
            if ($taskrow['runtimes'] < tostamp() - 3600) {
                $updata['autotaskstatus'] = 20;
                $runningmsg = '任务执行中，超过1小时，强制复位';
            }
        } else {
            $updata['autotaskstatus'] = 30;
            $updata['runtimes'] = tostamp();
        }
        $updata['nexttimes'] = $nexttimes;
        $csql = new \ciy\sql('zc_autotask');
        $csql->where('id', $sysid);
        $db->update($csql, $updata);
        if ($taskrow['autotaskstatus'] == 30) {
            $updata = array();
            $updata['autotaskid'] = $sysid;
            $updata['addtimes'] = tostamp();
            $updata['runsec'] = -1;
            $updata['logcnt'] = 0;
            $updata['msg'] = $runningmsg;
            $csql = new \ciy\sql('zc_autotsk_run');
            $db->insert($csql, $updata);
            return $db->insert_id();
        }
        $runlogstart = tostamp();
        $updata = array();
        $updata['autotaskid'] = $sysid;
        $updata['addtimes'] = $runlogstart;
        $csql = new \ciy\sql('zc_autotsk_run');
        $db->insert($csql, $updata);
        $runtaskid = $db->insert_id();
        $taskrow['runtaskid'] = $runtaskid;
        $taskrow['runtimes'] = tostamp();
        $taskrow['running'] = function () use ($db, &$taskrow) {
            if (time() - $taskrow['runtimes'] < 3)
                return;
            $taskrow['runtimes'] = tostamp();
            $csql = new \ciy\sql('zc_autotask');
            $csql->where('id', $taskrow['id']);
            $db->update($csql, array('runtimes' => $taskrow['runtimes']));
        };
        $taskrow['log'] = function ($msg) use ($db, &$taskrow) {
            if (empty($msg))
                return;
            $updata = array();
            $updata['autotaskid'] = $taskrow['id'];
            $updata['runtaskid'] = $taskrow['runtaskid'];
            $updata['addtimes'] = tostamp();
            $updata['msg'] = $msg;
            $csql = new \ciy\sql('zc_autotsk_log');
            $db->insert($csql, $updata);
        };
        $msg = '';
        try {
            clog($taskrow['name'] . ' 开始执行...');
            $funcs = explode('::', $taskrow['runfunc']);
            if (!class_exists($funcs[0]))
                throw new \Exception('无效类:' . $funcs[0]);
            if (!method_exists($funcs[0], $funcs[1]))
                throw new \Exception('无效函数:' . $funcs[0] . '::' . $funcs[1]);
            $msg = call_user_func($taskrow['runfunc'], $taskrow);
            clog($taskrow['name'] . ' 执行完成。<br/>' . $msg);
        } catch (\Exception $ex) {
            $msg = $ex->getMessage();
        }
        $runsec = tostamp() - $runlogstart;
        $updata = array();
        $updata['autotaskstatus'] = 20;
        $updata['runtimes'] = 0;
        $csql = new \ciy\sql('zc_autotask');
        $csql->where('id', $sysid);
        $db->update($csql, $updata);

        $csql = new \ciy\sql('zc_autotsk_log');
        $csql->where('runtaskid', $runtaskid);
        $logcnt = $db->get1($csql);
        $updata = array();
        $updata['runsec'] = $runsec;
        $updata['msg'] = dbstr($msg, 200);
        $updata['logcnt'] = $logcnt;
        $csql = new \ciy\sql('zc_autotsk_run');
        $csql->where('id', $runtaskid);
        $db->update($csql, $updata);
        return $runtaskid;
    }
}
