<?php

require_once realpath(dirname(__FILE__)) . '/../common.php';

$index = (int) $argv[1];
if (!singleProcess(getCurrentCommand(), ROOT_PATH . "/bin/run/checkGames_{$index}.pid")) {
    exit("Sorry, this script file has already been running ...\n");
}

// $index = 1;

$objOffer = new Offer();
$listKey = 'globals:baccarat:game_list';
$revealPreKey = 'globals:baccarat:game_reveal:';
$objRedis = dwRedis::init(Eos::REDIS_SERV);
$objGame = new Game();

if ($index === 0) {
    // 获取正在进行中的游戏
    for ($i = 0; $i < 1000; $i++) {
        // 获取当前有几个房间，是否可以要开奖
        $keyWord = [
            '_sortKey' => 'update_time_int ASC',
            '_field' => 'id, ttl, create_time, update_time_int'
        ];
        $games = $objGame->objTable->getAll(['game_state' => Game::STATUS_PLAYING], $keyWord);

        $ids = [];
        foreach ($games as $game) {
            $timeout = strtotime($game['create_time']) + $game['ttl'];
            $timeout = $timeout - time();
            if ($timeout <= 0) {
                $ids[] = $game['id'];

                // 设置开始时间
                $objRedis->setex($revealPreKey . $game['id'], 120, time());
            }
        }

        if ($ids) {
            $data = $ids;

            // 批量更新数据库
            $newData = ['game_state' => Game::STATUS_OPENING];
            $where = ['id' => $ids];
            $objGame->objTable->updateObject($newData, $where);
            Eos::log("lPush:" . join(',', $ids));

            // 批量插入redis
            array_unshift($data, $listKey);
            call_user_func_array([$objRedis, 'lPush'], $data);
        } else {

            Tool::sleep(1);
        }

        // 检查正在开奖中的游戏，是否正常
        $game_ids = $games = $objGame->objTable->getCol(['game_state' => Game::STATUS_OPENING], ['_field' => 'id']);
        $error_ids = [];
        foreach ($game_ids as $game_id) {
            $time = $objRedis->get($revealPreKey . $game_id);
            $span = time() - $time;
            // 处理事件超过了30秒，则认为是异常的游戏
            if ($span > 30) {
                $msg = "百家乐游戏超时：{$game_id}, span:{$span}，设置game_state=0";
                Eos::log($msg);
                $error_ids[] = $game_id;
            }
        }

        if ($error_ids) {
            $newData = ['game_state' => 0];
            $where = ['game_state' => 1, 'id' => $error_ids];
            $objGame->objTable->updateObject($newData, $where);
        }

    }
} else {
    $objSyncOffer = new Sync_Offer();
    $objEos = new Eos();
    for ($i = 0; $i < 1000; $i++) {
        // 获取要开奖的游戏
        $game_id = $objRedis->rPop($listKey);
        if (!$game_id) {
            Tool::sleep(1);
            continue;
        }

        Eos::log("rPop: {$game_id}");
        // 设置开始处理时间
        $objRedis->setex($revealPreKey . $game_id, 120, time());

        $game = $objGame->objTable->getRow(['id' => $game_id]);
        if ($game['game_state'] != Game::STATUS_OPENING) {
            Eos::log("skig, game_state: {$game['game_state']}");
            continue;
        }

        $timeout = strtotime($game['create_time']) + $game['ttl'];
        $timeout = $timeout - time();
        try {
            if ($timeout <= 0) {

                // 开奖并充值
                Eos::log("revealCreate gameid: {$game['id']}");
                $newGameId = $objEos->revealCreate($game, $objGame);

                $json = Eos::$last_json;
                if ($newGameId) {
                    // 同步订单状态
                    $objSyncOffer->pubSubscribe(false);

                    // 开奖后，同步游戏数据
                    $objSyncGame = new Sync_Game();
                    $objSyncGame->pubSubscribe(false);


                } else {
                    // 交易太长的告警跳过
                    if (strpos($json, 'Transaction took too long') === false || $timeout <= -10) {
                        $msg = "游戏id:{$game_id} 开奖异常，timeout:{$timeout}, 重新放入队列. json:{$json}";
                        errorGame($game_id, $msg);
                    } else {
                        resetGame($game_id);
                    }

                    sleep(1);
                }

                CallLog::logSelfCall(CODE_SUCCESS, "checkGames_{$index}, times:{$i}, timeout:{$timeout}");

                global $startTime;
                $startTime = microtime(true);
            } else {
                $msg = "游戏id:{$game_id} 还没到开奖时间，重新放入队列.";
                errorGame($game_id, $msg);
            }
        } catch (Exception $ex) {
            $msg = "游戏id:{$game_id} 未知异常，重新放入队列. 异常：" . $ex->getMessage();
            errorGame($game_id, $msg);
        }
    }

}


function resetGame($game_id) {
    global $objGame;

    // 异常情况
    $newData = ['game_state' => Game::STATUS_PLAYING];
    $where = ['id' => $game_id, 'game_state' => Game::STATUS_OPENING];
    $objGame->objTable->updateObject($newData, $where);
}

function errorGame($game_id, $msg) {
    resetGame($game_id);

//    $msg = "游戏id:{$game_id} 还没到开奖时间，重新放入队列.";
    alermErrorMsg($msg);
    Eos::log($msg);
}



