#!/usr/bin/env php
<?php
/**
 * 客户端 Session 统一缓存策略回归
 */
if (PHP_SAPI !== 'cli') {
    exit(1);
}

$root = dirname(__DIR__);
require_once $root . '/cong.php';
require_once $root . '/lib/Cloak/RiskSecondaryGate.php';
require_once $root . '/lib/Cloak/CloakJudgmentCache.php';

if (!defined('CLOAK_RISK_NUMBER')) {
    define('CLOAK_RISK_NUMBER', 51);
}
if (!defined('COSTM_IP_SCORE')) {
    define('COSTM_IP_SCORE', 'judgment_cache_test');
}

$_SESSION = [];
$tests = [];

// byApi + 风险开启 → partial
CloakJudgmentCache::storeFromByApi([
    'ip'      => '10.0.0.1',
    'country' => 'US',
    'result'  => 'true',
    'reason'  => 'api pass',
]);
$tests['byapi_with_risk_is_partial'] = CloakJudgmentCache::isPartial();
$tests['partial_not_final'] = !CloakJudgmentCache::isFinal();
$tests['partial_fast_path_miss'] = CloakJudgmentCache::getFinal() === null;

$cachedPartial = CloakJudgmentCache::get();
if (CloakJudgmentCache::isPartial($cachedPartial)) {
    CloakJudgmentCache::applyToSession($cachedPartial);
    $_SESSION['visit_to_2'] = '2';
}
$tests['partial_resume_hit'] = CloakJudgmentCache::isPartial($cachedPartial);
$tests['partial_resume_sets_visit_to_2'] = ($_SESSION['visit_to_2'] ?? '') === '2';
$tests['partial_keeps_visit_to_3_open'] = ($_SESSION['visit_to_3'] ?? '') === '1';

// byApi false → final even with risk
$_SESSION = [];
CloakJudgmentCache::storeFromByApi([
    'ip'      => '10.0.0.2',
    'country' => 'US',
    'result'  => 'false',
    'reason'  => 'api deny',
]);
$tests['byapi_false_is_final'] = CloakJudgmentCache::isFinal();

// byApiRisk → final
$_SESSION = [];
CloakJudgmentCache::storeFromByApiRisk([
    'ip'      => '10.0.0.3',
    'country' => 'CA',
    'result'  => 'true',
    'reason'  => '',
    'fp_url'  => 'https://fp/x',
]);
$finalCached = CloakJudgmentCache::getFinal();
$tests['final_fast_path_hit'] = $finalCached !== null;
if (is_array($finalCached)) {
    CloakJudgmentCache::applyToSession($finalCached);
}
$tests['final_applies_check_result'] = ($_SESSION['check_result'] ?? '') === 'true';

// 无 Session 缓存
$_SESSION = [];
$tests['empty_session_no_cache'] = CloakJudgmentCache::get() === null;

$noRiskCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
    'define("CLOAK_RISK_NUMBER",0);'
    . 'require ' . var_export($root . '/lib/Cloak/RiskSecondaryGate.php', true) . ';'
    . 'require ' . var_export($root . '/lib/Cloak/CloakJudgmentCache.php', true) . ';'
    . '$_SESSION=[];'
    . 'CloakJudgmentCache::storeFromByApi(["ip"=>"10.0.0.4","country"=>"US","result"=>"true","reason"=>""]);'
    . '$c=$_SESSION["cloak_judgment_cache"]??[];'
    . 'echo (CloakJudgmentCache::isFinal() && ($c["stage"]??"")==="final" && CloakJudgmentCache::getFinal()!==null) ? "1" : "0";'
);
$tests['byapi_no_risk_is_final'] = trim((string) shell_exec($noRiskCmd)) === '1';

$legacyByapiCmd = escapeshellarg(PHP_BINARY) . ' -r ' . escapeshellarg(
    'define("CLOAK_RISK_NUMBER",0);'
    . 'require ' . var_export($root . '/lib/Cloak/RiskSecondaryGate.php', true) . ';'
    . 'require ' . var_export($root . '/lib/Cloak/CloakJudgmentCache.php', true) . ';'
    . '$_SESSION=["cloak_judgment_cache"=>["stage"=>"byapi","ip"=>"10.0.0.5","country"=>"US","result"=>"true","reason"=>"","fp_url"=>"","risk_number"=>0,"campaign_id"=>"x","cached_at"=>1]];'
    . 'echo (CloakJudgmentCache::isFinal() && CloakJudgmentCache::getFinal()!==null && !CloakJudgmentCache::isPartial()) ? "1" : "0";'
);
$tests['risk_zero_treats_legacy_byapi_as_final'] = trim((string) shell_exec($legacyByapiCmd)) === '1';

$ok = !in_array(false, $tests, true);
echo json_encode(['ok' => $ok, 'tests' => $tests], JSON_UNESCAPED_UNICODE) . "\n";
exit($ok ? 0 : 1);
