<?php
declare(strict_types=1);
$root=$argv[1]??'';$file=$root.'/application/common/service/account/GiftFlowRead.php';if(!is_file($file)){fwrite(STDERR,"RED: GiftFlowRead absent in source\n");exit(1);}require $file;
use app\common\service\account\GiftFlowRead as G;
class GiftTestDb {private $type;public function __construct($type){$this->type=$type;}public function getConfig($key){if($key!=='type')throw new RuntimeException('Unexpected config');return $this->type;}}
$dm=new GiftTestDb('\\app\\cores\\database\\Dm');$mysql=new GiftTestDb('mysql');$unknown=new GiftTestDb('other');$count=0;
$check=static function($ok,$why)use(&$count){$count++;if(!$ok)throw new RuntimeException($why);};$reject=static function($fn,$why)use($check){try{$fn();}catch(UnexpectedValueException $e){$check(true,$why);return;}$check(false,$why);};
$fields='log_id,biz_order_id';$check(G::project($mysql,$fields)===$fields,'MySQL projection unchanged');$check(G::project($unknown,$fields)===$fields,'Unknown projection unchanged');$check(G::project($dm,$fields)===$fields.',CAST(biz_order_id AS VARCHAR(40)) AS gift_biz_order_id_exact','Explicit DM projection');
$vectors=['0'=>0,'9007199254740991'=>9007199254740991,'9007199254740993'=>9007199254740993,'9223372036854775807'=>PHP_INT_MAX,'18446744073709551615'=>'18446744073709551615'];foreach($vectors as $text=>$expected){$text=(string)$text;$check(G::unsigned($text)===$expected,'Exact source type '.$text);foreach(['biz_order_id','order_id']as $field){$row=[$field=>0.0,'gift_biz_order_id_exact'=>$text,'unrelated'=>'keep'];$got=G::restore($dm,$row,$field);$check($got===[$field=>$expected,'unrelated'=>'keep'],'Restore target/remove helper '.$field);$check(G::restore($mysql,$row,$field)===$row,'MySQL identity '.$field);}$check((int)G::unsigned($text)===(int)$text,'Preserve original Wallet int contract');}
$check(G::unsigned(null)===null,'Null preserved');$check(G::unsigned('0000')===0,'Zero canonical');$check(G::unsigned('0009007199254740993')===9007199254740993,'Leading zero canonical');foreach([0,0.0,9007199254740992.0,true,false,[],new stdClass(),'','-1','+1','1.0','1e3',' 1','1 ' ,"1\n",'18446744073709551616']as $bad)$reject(static function()use($bad){G::unsigned($bad);},'Reject invalid exact text');
$reject(static function()use($dm){G::restore($dm,['order_id'=>0.0],'order_id');},'Missing helper fails declared DM read');$reject(static function()use($dm){G::restore($dm,['gift_biz_order_id_exact'=>'1'],'unknown');},'Unknown target rejected');$check(G::restore($dm,['order_id'=>1,'gift_biz_order_id_exact'=>null],'order_id')===['order_id'=>null],'Null helper no leakage');
$reject(static function()use($dm){G::restore($dm,['gift_biz_order_id_exact'=>'1'],'order_id');},'Missing declared original field rejected');$row=['unexpected'=>false,'gift_biz_order_id_exact'=>2.5];$check(G::restore($mysql,$row,'unknown')===$row,'MySQL invalid target remains no-op');
for($i=1;$i<=6;$i++){$value='2024-02-29 23:59:59.'.str_repeat('0',$i);$check(G::accountTime($dm,$value)==='2024-02-29 23:59:59','Valid zero microseconds');$check(G::accountTime($mysql,$value)===$value,'MySQL time unchanged');}
foreach([null,0,'','2026-02-29 00:00:00.000000','2024-02-30 00:00:00.0','2024-13-01 00:00:00.0','2024-01-01 24:00:00.0','2024-01-01 23:60:00.0','2024-01-01 23:59:60.0','2024-01-01 23:59:59.000001','2024-01-01 23:59:59.0000000',"2024-01-01 23:59:59.0\n",'2024-01-01 23:59:59','0000-01-01 00:00:00.0','0999-01-01 00:00:00.0','0001-01-01 00:00:00.0']as $value)$check(G::accountTime($dm,$value)===$value,'Invalid/nonzero/null date unchanged');
echo json_encode(['assertions'=>$count,'passed'=>true,'PDO'=>0,'SQL'=>0]),"\n";
