<?php
// Pure tool tests. No config, PDO connection, SQL or HTTP.
require __DIR__.'/runner.php';
$plan=json_decode(file_get_contents(__DIR__.'/plan.json'),true);
$checks=0;$rejected=0;
$assert=static function($ok,$reason)use(&$checks){++$checks;if(!$ok)throw new RuntimeException($reason);};
$deny=static function($call,$reason)use($assert,&$rejected){try{$call();}catch(Throwable $e){++$rejected;$assert(true,$reason);return;}$assert(false,'Not rejected: '.$reason);};
$assert(pc_gate_plan($plan)===['read'=>132,'DML'=>28,'DDL'=>5],'Exact165-step C ledger');
foreach($plan['steps']as $i=>$s){$state=['cursor'=>$i,'read'=>0,'DML'=>0,'DDL'=>0,'created'=>true,'trigger_created'=>true,'collision_zero'=>true,'drop_proof'=>true,'table_drop_proof'=>true];if($s['role']==='create'){$state['created']=false;$state['trigger_created']=false;}if($s['role']==='create_trigger')$state['trigger_created']=false;pc_gate_step($plan,$s,$state);$assert(true,'Literal accepted');}
foreach(['B','budget','unknown_SQL','wrong_bind','wrong_type','missing_WHERE','foreign_lease','missing_step','C_endpoint','trigger_literal']as $kind){$bad=$plan;
 if($kind==='B')$bad['lane']='B';if($kind==='budget')$bad['budget']['read']=181;
 if($kind==='unknown_SQL')$bad['steps'][0]['SQL']='SELECT * FROM YDY_USER';
 if($kind==='wrong_bind')$bad['steps'][array_search('CAS4',array_column($bad['steps'],'label'))]['binds'][0]=999;
 if($kind==='wrong_type')$bad['steps'][array_search('CAS4',array_column($bad['steps'],'label'))]['PDO_types'][0]=2;
 if($kind==='missing_WHERE')$bad['steps'][array_search('CAS4',array_column($bad['steps'],'label'))]['SQL']='UPDATE ZHCT_APP.CDX_PPUT261011_S1 SET USER_ID=9';
 if($kind==='foreign_lease')$bad['marker']='OTHER';if($kind==='missing_step')array_pop($bad['steps']);
 if($kind==='C_endpoint')$bad['connection']['port']='5238';
 if($kind==='trigger_literal')$bad['source_hashes']['candidate_trigger_file_sha256']=str_repeat('0',64);
 $deny(static function()use($bad){pc_gate_plan($bad);},$kind);
}
foreach(['create','create_trigger','drop_trigger','drop_table']as $role){$i=array_search($role,array_column($plan['steps'],'role'));$step=$plan['steps'][$i];$st=['cursor'=>$i,'read'=>0,'DML'=>0,'DDL'=>0,'created'=>true,'trigger_created'=>true,'collision_zero'=>true,'drop_proof'=>true,'table_drop_proof'=>true];if($role==='drop_trigger')$st['drop_proof']=false;if($role==='drop_table')$st['table_drop_proof']=false;$deny(static function()use($plan,$step,$st){pc_gate_step($plan,$step,$st);},'DDL ownership/replay '.$role);}
$rows=pc_fixture_rows($plan);$types=pc_fixture_types($rows);
pc_snapshot($rows,[1,2,3,4],0,$plan);$assert(true,'Full10 plus CLOB/null/byte/fsp/clock helpers');
foreach(['lease','date_fraction','CLOB_empty','HEX','rowset']as $kind){$bad=$rows;if($kind==='lease')$bad[0]['lease_id']='OTHER';if($kind==='date_fraction')$bad[0]['f_update_time']='2001-01-01 00:00:00.00000';if($kind==='CLOB_empty')$bad[0]['r_null']='0';if($kind==='HEX')$bad[0]['h_lease_id']='00';if($kind==='rowset')$bad[3]['id']=9;$deny(static function()use($bad,$plan){pc_snapshot($bad,[1,2,3,4],0,$plan);},$kind);}
foreach($plan['cases']as $c){$before=$rows;foreach(array_slice($plan['columns'],1)as $i=>$col)$before[0][strtolower($col)]=$c['reset_binds'][$i];$before[0]=pc_fixture_refresh($before[0]);$bt=pc_fixture_types($before);pc_transition($rows,$before,$types,$bt,$c['label'],'reset',true,null,$plan);$after=$before;
 if($c['label']==='CAS4'){foreach(['meal_order_id'=>7,'meal_order_no'=>'CDXPPUT261011S1_ORDER','user_id'=>8,'update_by'=>'miniapp']as $k=>$v)$after[0][$k]=$v;}
 if($c['label']==='VARCHAR_CASE')$after[0]['update_by']='leasea';if(strpos($c['label'],'CLOB_')===0)$after[0]['raw_request_a']=$c['binds'][0];
 if(strpos($c['label'],'EXPLICIT_')===0)$after[0]['meal_order_id']=7;
 if($c['label']==='EXPLICIT_VALUE_CHANGED')$after[0]['update_time']='2001-01-01 09:07:26';
 elseif(!in_array($c['label'],['NOOP_SCALAR','EXPLICIT_SELF_CHANGED','EXPLICIT_NULL_CHANGED','CLOB_SAME','ALL9_SELF'],true))$after[0]['update_time']=$after[0]['clock0'];
 $after[0]=pc_fixture_refresh($after[0]);$at=pc_fixture_types($after);
 if($c['label']==='EXPLICIT_NULL_CHANGED'){pc_transition($before,$before,$bt,$bt,$c['label'],'mutation',false,['HY000',-6609,'Column not null'],$plan);$assert(true,'Original C NULL error retained');}
 else{pc_transition($before,$after,$bt,$at,$c['label'],'mutation',true,null,$plan);$assert(true,'Complete source-bounded C mutation '.$c['label']);$bad=$after;$bad[0]['expire_time']='2002-01-01 00:00:00';$bad[0]=pc_fixture_refresh($bad[0]);$deny(static function()use($before,$bad,$bt,$c,$plan){pc_transition($before,$bad,$bt,pc_fixture_types($bad),$c['label'],'mutation',true,null,$plan);},'Valid-looking unpermitted row1 date '.$c['label']);}
}
$deny(static function()use($rows,$types,$plan){pc_transition($rows,$rows,$types,$types,'EXPLICIT_NULL_CHANGED','reset',false,['HY000',-6609,'Column not null'],$plan);},'Reset failure never treated as NULL oracle');
$deny(static function()use($rows,$types,$plan){pc_transition($rows,$rows,$types,$types,'EXPLICIT_NULL_CHANGED','mutation',false,['HY000',-2007,'Unknown syntax'],$plan);},'Unknown error never continued');
$initial=array_slice($rows,0,3);foreach($initial as $i=>&$r){foreach(['expire_time','create_time','update_time']as $k){$r[$k]=$i===0?$r[$k].'.000000':'2001-01-01 01:01:01.'.($i===1?'499999':'500000');$r['f_'.$k]=$r[$k];}}unset($r);$mapped=$initial;foreach($mapped as $i=>&$r){foreach(['expire_time','create_time','update_time']as $k)$r[$k]=$i===0?substr($r[$k],0,19):($i===1?'2001-01-01 01:01:01':'2001-01-01 01:01:02');$r=pc_fixture_refresh($r);}unset($r);pc_snapshot($initial,[1,2,3],6,$plan);pc_snapshot($mapped,[1,2,3],0,$plan);pc_alter_rows($initial,$mapped,pc_fixture_types($initial),pc_fixture_types($mapped),$plan);$assert(true,'Real fractions/calibration fixture separate from generated defaults');$bad=$mapped;$bad[2]['update_time']='2001-01-01 01:01:01';$bad[2]=pc_fixture_refresh($bad[2]);$deny(static function()use($initial,$bad,$plan){pc_alter_rows($initial,$bad,pc_fixture_types($initial),pc_fixture_types($bad),$plan);},'No pre-truncation of source .500000');
$approved=pc_reference()['create_trigger'];pc_trigger($approved,$approved,$approved);$assert(true,'Full trigger header/body tokens');foreach(['literal','owner']as $kind){$bad=$kind==='literal'?str_replace("'#'","'$'",$approved):str_replace('ZHCT_APP.CDX_PPUT261011_S1','ZHCT_APP.YDY_PREPAY_ORDER',$approved);$deny(static function()use($bad,$approved){pc_trigger($bad,$bad,$approved);},'Trigger full source '.$kind);}
echo json_encode(['status'=>'PURE_C_GATE_TESTS_PASS','checks'=>$checks,'counterexamples'=>$rejected,'literal_read'=>132,'literal_DML'=>28,'literal_DDL'=>5,'DB_connections'=>0,'SQL'=>0,'HTTP'=>0]),"\n";

function pc_fixture_refresh($r){foreach(['id','meal_order_id','user_id']as $k)$r['h_'.$k]=(string)$r[$k];foreach(['lease_id','meal_order_no','update_by']as $k)$r['h_'.$k]=$r[$k]===''?null:strtoupper(bin2hex($r[$k]));$r['r_null']=$r['raw_request_a']===null?'1':'0';foreach(['expire_time','create_time','update_time']as $k)$r['f_'.$k]=$r[$k].'.000000';return $r;}
function pc_fixture_rows($p){$rows=[];foreach([1,2,3,4]as $id){$r=['id'=>$id,'lease_id'=>$p['marker'],'meal_order_id'=>0,'meal_order_no'=>'','user_id'=>0,'update_by'=>'leaseA','raw_request_a'=>null,'expire_time'=>'2000-01-01 00:00:00','create_time'=>'2001-01-01 00:00:00','update_time'=>'2001-01-01 00:00:00'];$r['clock_raw']='2026-10-11 10:00:00.123456 +08:00';$r['clock0']='2026-10-11 10:00:00';$r['clock6']='2026-10-11 10:00:00.123456';$rows[]=pc_fixture_refresh($r);}return $rows;}
function pc_fixture_types($rows){return array_map(static function($r){return array_map('gettype',$r);},$rows);}
