<?php
define('IN_WEB', true);

class GatewayNew {
    public function start($aRequest) {
        //$calStart = oo::timeReleased();
        if(isset($aRequest['saToken']) && isset($aRequest['uid'])) {
            if(!isset($aRequest['saToken'])) {
                return json_encode(['code'=>errorCode::UNAUTHORIZED_REQUEST,'msg'=>'token empty']);
            }else{
                $token = oo::commonOprRedis('common')->get(okeys::UserToken($aRequest['uid']));
                if($token != $aRequest['saToken'] && !IS_DEBUF){
                    oo::logs()->debug3(["ts"=>date("H:i:s"),"uid"=>$aRequest['uid'],'cacheToke'=>$token,'postToken'=>$aRequest['saToken']],'tokenerr.log');
                    return json_encode(['code'=>errorCode::API_TIME_EXPIRED,'msg'=>'token error']);
                }
            }
        }else if(isset($aRequest['uid'])){
            oo::logs()->debug3(["ts"=>date("H:i:s"),"uid"=>$aRequest['uid'],'postToken'=>$aRequest['saToken']],'tokenerr2.log');
        }
        if (!is_array($aRequest)) {
            return json_encode(['code'=>errorCode::REQUEST_PARAM_ERROR,'msg'=>'request is wrong']);
        }
        $aRequest['version'] = isset($aRequest['version']) ? $aRequest['version'] : '1.0.0';
        if (!empty($aRequest['mod'])) {
            $class = preg_replace("/[^a-zA-Z]/", '', trim($aRequest['mod']));
            $class = ucfirst($class);
        } else {
            $class = 'Main';
        }
        /* 获得 act 名 */
        if ( ! empty($aRequest['act'])) {
            $function = preg_replace("/[^a-zA-Z]/", '', trim($aRequest['act']));
            if ($function == 'list') {
                $function = 'listFunction';
            } elseif ( $function == 'main') {
                $function = 'mainFunction';
            }
        } else {
            $function = 'page';
        }

        if(!empty($aRequest['frombg'])){
            return json_encode(['code'=>-1,'msg'=>'background api forbidden']);
        }

        //只保留几个响应时间比较长的key
        $actKey = $aRequest['mod'].'_'.$aRequest['act'];
        $superStoreKeys = ['Friend_SynchronizeFb', 'Friend_receiveGifts', 'Friend_giftList', 'User_enemyList'];

        $apiFile = 'services';
        if(isset($aRequest['superKey']) && in_array($actKey, $superStoreKeys)) {
            $ret = oo::commonOprRedis('statistics')->get(okeys::superKeys($aRequest['uid'],$class,$function,$aRequest['superKey']));
            if($ret){
                return $ret;
            }
        }

        if(isset($aRequest['service'])){
            $apiFile = 'services_2';
        }

        if($apiFile == 'services'){
            //oo::logs()->debug3(['req' => $aRequest], 'oldapi'); //记录哪些老接口还在被调用
            return json_encode(['code'=>-1,'msg'=>'old api forbidden']); //老接口停止调用
        }

        $file = WWWROOT . 'api/'.$apiFile.'/' . $class . '.php';
        if(!in_array($file, get_included_files()) && !class_exists($class)){
            if (!is_file($file)) {
                return json_encode(['code'=>errorCode::REQUEST_PARAM_ERROR,'msg'=>'no file services']);
            }
            include_once $file;
        }

        $obj = new $class();

        if (!method_exists($obj, $function)) {
            return json_encode(['code'=>errorCode::REQUEST_PARAM_ERROR,'msg'=>'no function:'.$function.'in '.$class.$apiFile]);
        }

        //记录所有api请求记录,未响应的也记录
        oo::commonOprModel('statistics')->apiRequestLog('gateway_'.$class, $function);

        $ts1 = oo::getMsectime();
        //奖励等部分接口请求频率限制
        $lock = true;
        if(in_array($apiFile, ['services', 'services_2'])){
            //$confs = oo::cfg('cmdlimit');
            //$lock = true;
            //if(!empty($confs[$apiFile]) && in_array((string)$aRequest['mod'].'.'.(string)$aRequest['act'], $confs[$apiFile])){
            //    $lock = funs::concurrentLock($aRequest['uid'], $apiFile.(string)$aRequest['mod'].(string)$aRequest['act'], 1);
            //}
            $lock = funs::concurrentLock($aRequest['uid'], $apiFile.(string)$aRequest['mod'].(string)$aRequest['act'], 1);
            if(!$lock){ //高频请求
                usleep(100000); //延迟100毫秒
            }
        }
        $result = $obj->$function($aRequest);
        //echo $result;

        if(!$lock){ //高频请求记录详细信息,分析客户重复请求行为
            //!in_array($aRequest['mod'].'_'.$aRequest['act'],['Level_build','Goods_list']) && oo::logs()->debug3(['req' => $aRequest, 'rsp' => $result], 'frequentapi.log');
            //exit(oo::response(errorCode::API_FREQUENT_REQUESTS));
        }

        $ts2 = oo::getMsectime();
        if(isset($aRequest['superKey']) && in_array($actKey, $superStoreKeys)) {
            oo::commonOprRedis('statistics')->setex(okeys::superKeys($aRequest['uid'],$class,$function,$aRequest['superKey']),$result,20);
            $lastApi=["mod_act"=>$aRequest['mod'].'_'.$aRequest['act'],"request"=>$aRequest,"result"=>$result,"ts1"=>$ts1,"ts2"=>$ts2];
            //oo::commonOprRedis('statistics')->setex(okeys::lastApiReturn($aRequest['uid']),json_encode($lastApi),60*10);//记录最后请求接口
        }
        if(!in_array($apiFile, ['services', 'services_2'])){
            return $result;
        }
        if($ts2-$ts1>2000){//超时长接口
            oo::logs()->debug3(['time'=>date("Y-m-d H:i:s"),"uid"=>$aRequest['uid'],"expend_ts"=>($ts2-$ts1),"mod"=>$aRequest['mod'],"act"=>$aRequest['act']], 'expend_ts_http.log');
        }
        return $result;
    }
}
