<?php
    // 主判定块：API 远程判定 + 前端指纹（Guard 之后执行）
    if(empty($_SESSION["check_result"]) )      // 缓存里没有判断结果或者判断结果是跳转安全站
    {
    if (class_exists('CloakPipelineTimer', false)) {
        CloakPipelineTimer::stage('API与指纹准备');
    }
    if ($__cloak_debug_on) {
        cloak_dbg_step(__LINE__,'主判定块 (API+指纹)', 'info', 'check_result 为空，进入 API/指纹 判定块');
    }
    if(empty($_SESSION['visit_to_1']))      // 重置session信息
    {
        $_SESSION['visit_to_1'] = '1';
        $_SESSION['visit_to_2'] = '1';
        $_SESSION['visit_to_3'] = '1';
        $_SESSION["gcu_country"] = '';      // IP国家
        $_SESSION["gcu_Client"] = '';
        $_SESSION["gcu_ip"] = '';
        $_SESSION["gcu_Browser"] = '';
        if (class_exists('VisitorApiAudit', false)) {
            VisitorApiAudit::clearByApi();
        }
    }
    
    if (($_SESSION['visit_to_2'] ?? '') == '2' && class_exists('CloakJudgmentCache', false) && !CloakJudgmentCache::hasSession()) {
        $_SESSION['visit_to_2'] = '1';
    }

    if($_SESSION['visit_to_1'] == '1' && $_SESSION['visit_to_2'] != '2')    // $_SESSION['visit_to_2'] 为2时表示已经判断过所有规则。
    {
        if ($__cloak_debug_on) {
            cloak_dbg_step(__LINE__,'主判定块 (API)', 'info', 'visit_to_1=1 且 visit_to_2!=2，执行 API 调用条件满足');
        }
        if(CLOAK_V_REFERER == "OFF" && $v_info->v_referer == "") {
            $v_info->v_referer = 'off';
        }
        
        if(isset($_COOKIE['vbrowser']) && $_COOKIE['vbrowser'] == 'mobile') {
            $_SESSION["gcu_Browser"] = 'mobile';
        } else {
            $_SESSION["gcu_Browser"] = 'pc';
        }

        if($v_info->v_referer != "")                //排除机器访问，赋值给 _COOKIE ， _SESSION
        {
            //echo $v_info->v_referer;
            $v_info->get_visit_md5_code();          //生成客户信息md5
            $v_referer_str = $v_info->v_referer;    /* && $v_info->accept_language != "Chinese"*/
            if(!empty($v_referer_str) && !empty($v_info->accept_language) /* && $v_info->v_Browser != "unknown" && ( strpos($v_referer_str,"google") || strpos($v_referer_str,"bing") || strpos($v_referer_str,"yahoo") || strpos($v_referer_str,"facebook") || strpos($v_referer_str,"yandex")) */)
            {
                setCrossDomainCookie("gfuid", $v_info->visit_md5_code, time()+3600*24);
                $_SESSION["gcu_country"] = $v_info->v_country;
                $_SESSION["gcu_Client"] = $v_info->v_Client;
                $_SESSION["gcu_ip"] = $v_info->v_ip;
                $_SESSION["gcu_Browser"] = empty($_SESSION["gcu_Browser"])?$v_info->v_Browser:$_SESSION["gcu_Browser"];
            }
            $_SESSION["gcuid"] = $v_info->visit_md5_code;
        } elseif( !empty($_COOKIE["gfuid"]) ) {
            $_SESSION["gcuid"] = $_COOKIE["gfuid"];
            $v_info->v_referer = "COOKIE: " . cloak_current_request_url();
            $v_info->set_visit_md5_code($_COOKIE["gfuid"]); //赋值客户信息md5
        }
        
        if(!empty($_SESSION["gcuid"]) && !empty($v_info->v_referer))
        {
            if ($__cloak_debug_on) {
                cloak_dbg_step(__LINE__,'Referer / gcuid', 'pass', 'gcuid 与 referer 均存在，可进入指纹/API 判定', [
                    'gcuid' => $_SESSION['gcuid'],
                    'referer' => $v_info->v_referer,
                ]);
            }
            if(strtoupper(CLOAK_ZH_ON) == "ON" || strtoupper(CLOAK_MOBILE_ON) == "ON" || strtoupper(CLOAK_OS_ON) == "ON" || intval(IPHONE_MODEL) > 0 || intval(IS_VIRTUAL) > 0) {
                if (class_exists('CloakPipelineTimer', false)) {
                    CloakPipelineTimer::stage('指纹检测');
                }
                
                if (cloak_fingerprint_cookies_ready()) {
                    if ($_COOKIE['cl'] == 'uklot' && is_numeric($_COOKIE['ctime'])) {
                        $v_info->check_result = 'false';
                        $mmr = cloak_fingerprint_mmr_reason();
                        $reason = '可疑访客：' . $mmr;
                        $_SESSION['check_result'] = trim($v_info->check_result);
                        if ($__cloak_debug_on) {
                            cloak_dbg_record(__LINE__, trim($v_info->check_result), $reason, ['stage' => 'fingerprint_cookie', 'mmr' => $mmr]);
                        }
                    } else {
                        $v_info->check_result = 'true';
                    }
                } elseif (cloak_fingerprint_time_param_present()) {
                    // 已完成指纹跳转（URL 含 time），但 Cookie 未写入：终止再次重定向
                    $v_info->check_result = 'false';
                    
                    $reason = cloak_reason_or($reason, '已完成前端检测，但指纹Cookie未写入(隐私模式、广告拦截等可能阻止Cookie写入)');
                    $_SESSION['check_result'] = 'false';
                    if ($__cloak_debug_on) {
                        cloak_dbg_step(__LINE__, 'JS 指纹检测', 'fail', 'URL 含 time 但指纹 Cookie 缺失，停止重定向');
                        cloak_dbg_record(__LINE__, 'false', $reason, ['stage' => 'fingerprint_cookie_missing']);
                    }
                } else {
                    if ($__cloak_debug_on) {
                        cloak_dbg_step(__LINE__, 'JS 指纹检测', 'skip', 'DEBUG 跳过指纹 JS 跳转，直接进入 API 判定');
                        CloakDebugPage::setFlag('skipped_fingerprint', true);
                        $v_info->check_result = 'true';
                    } elseif (!empty($GLOBALS['__cloak_simulation_on'])) {
                        $v_info->check_result = 'true';
                    } else {
                        FingerprintRedirectRenderer::renderAndExit($config_name);
                    }
                }
            } else {
                $v_info->check_result = 'true';
                if ($__cloak_debug_on) {
                    cloak_dbg_step(__LINE__,'JS 指纹检测', 'skip', 'ZH/Mobile/OS/机型检测均为 OFF，跳过指纹');
                }
            }

            if($v_info->check_result == 'true') {
                if (class_exists('CloakPipelineTimer', false)) {
                    CloakPipelineTimer::stage('API远程判定');
                }
                $__api_return = $v_info->send_visitor_Info_xyz();   // 使用CLOAK判断接口
                if ($__cloak_debug_on) {
                    if ($__api_return !== null) {
                        CloakDebugPage::setApiResponse([
                            'called'      => true,
                            'check_result'=> $v_info->check_result,
                            'reason'      => $v_info->v_reason,
                            'country'     => $v_info->v_country,
                            'result_raw'  => isset($__api_return['result']) ? ($__api_return['result'] ? 'true' : 'false') : '',
                            'raw'         => $__api_return,
                        ]);
                        cloak_dbg_step(__LINE__,'API 远程判定', 'decide', 'API 已返回', [
                            'api_result' => $v_info->check_result,
                            'api_reason' => $v_info->v_reason !== '' ? $v_info->v_reason : '(空)',
                        ]);
                    } else {
                        CloakDebugPage::setApiResponse([
                            'called'      => false,
                            'skip_reason' => '无法获取IP，未调用 API判断IP信息是否安全',
                        ]);
                        cloak_dbg_step(__LINE__,'API 远程判定', 'skip', '前置条件不满足，未调用 API', [
                            'v_ip' => $v_info->v_ip,
                            'v_Browser' => $v_info->v_Browser,
                            'accept_language' => $v_info->accept_language,
                        ]);
                    }
                }
                //echo "<br />获取到结果:".$v_info->check_result."<br />";
                $_SESSION["gcu_referer"] = $v_info->v_referer;
                $_SESSION["gcu_country"] = $v_info->v_country;
                $_SESSION['visit_to_2'] = '2';      // 记录接口调用结果缓存
                
                if ($__api_return !== null) {
                    $_SESSION["check_result"] = trim($v_info->check_result);
                    $reason = cloak_api_reason($__api_return, $_SESSION["check_result"]);
                    if (class_exists('CloakJudgmentCache', false)) {
                        CloakJudgmentCache::storeFromByApi([
                            'ip'      => $v_info->v_ip,
                            'country' => $v_info->v_country,
                            'result'  => $_SESSION['check_result'],
                            'reason'  => $reason,
                        ]);
                    }
                } else {
                    $_SESSION["check_result"] = "false";
                    $reason = cloak_reason_or($reason, 'API未调用：缺少访客信息(ip/Browser/Accept-Language)');
                }
                if ($__cloak_debug_on) {
                    cloak_dbg_record(__LINE__,$_SESSION['check_result'], $reason, [
                        'stage'      => 'api_cloak',
                        'api_reason' => $v_info->v_reason,
                    ]);
                }
            } elseif ($v_info->check_result == 'false') {
                $_SESSION["check_result"] = "false";
                $reason = cloak_reason_or($reason, '指纹检测未通过，未调用API');
            }
        } else {
            $_SESSION["check_result"] = "false";
            $reason = "爬虫";
            if ($__cloak_debug_on) {
                cloak_dbg_step(__LINE__,'Referer / gcuid', 'fail', 'gcuid 或 referer 为空，判定为爬虫', [
                    'gcuid' => $_SESSION['gcuid'] ?? '',
                    'referer' => $v_info->v_referer,
                ]);
                cloak_dbg_record(__LINE__,'false', $reason, ['stage' => 'no_referer_or_gcuid']);
            }
        }
    } elseif (($_SESSION['visit_to_2'] ?? '') == '2') {
        $cached = class_exists('CloakJudgmentCache', false) ? CloakJudgmentCache::get() : null;
        if ($cached !== null) {
            CloakJudgmentCache::applyToSession($cached);
            CloakJudgmentCache::applyToVisitorInfo($v_info, $cached);
            $_SESSION['check_result'] = trim((string) ($cached['result'] ?? 'false'));
            if ($reason === '') {
                if (CloakJudgmentCache::isPartial($cached)) {
                    $reason = 'Session byApi阶段缓存：待二次风控';
                } else {
                    $reason = ($_SESSION['check_result'] === 'true')
                        ? 'Session API缓存：判定通过'
                        : '缓存';
                }
            }
        } elseif (!empty($_SESSION["check_result"])) {
            if ($reason === '') {
                $reason = ($_SESSION['check_result'] === 'true')
                    ? 'Session API缓存：判定通过'
                    : '缓存';
            }
        } else {
            $_SESSION['check_result'] = 'false';
            $reason = cloak_reason_or($reason, 'Session状态异常(visit_to_2=2但无缓存结果)，默认安全页');
            $_SESSION['visit_to_2'] = '1';
            if (class_exists('CloakJudgmentCache', false)) {
                CloakJudgmentCache::clear();
            }
        }
        if ($__cloak_debug_on) {
            cloak_dbg_step(__LINE__,'主判定块 (API)', 'skip', 'visit_to_2=2，本块已跳过（' . $reason . '）');
        }
    }
} else {
    if ($reason === '') {
        $reason = ($_SESSION['check_result'] === 'true')
            ? '前置规则判定通过(主判定块已跳过)'
            : '前置规则判定拒绝(主判定块已跳过)';
    }
    if ($__cloak_debug_on) {
        cloak_dbg_step(__LINE__,'主判定块 (API)', 'skip', 'check_result 已有值，跳过主判定块');
        cloak_dbg_record(__LINE__,$_SESSION['check_result'] ?? 'false', $reason, ['stage' => 'session_partial']);
    }
}
