<?php
declare(strict_types=1);
set_exception_handler(static function(Throwable $e){$f=__DIR__.'/private/tool-failure-'.str_replace('.','-',sprintf('%.6f',microtime(true))).'.json';file_put_contents($f,json_encode(['class'=>get_class($e),'message'=>$e->getMessage(),'line'=>$e->getLine()],JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));chmod($f,0600);fwrite(STDERR,'Stopped; private failure saved'.PHP_EOL);exit(1);});$mode=$argv[1]??'';
if($mode==='puregate'){require __DIR__.'/Gate.php';FoodGate::$dry=true;$checks=0;foreach(['UPDATE ydy_user SET status=1','DELETE FROM tchef_sync_task','SELECT * FROM external_table','SELECT * FROM ydy_config; DELETE FROM ydy_config']as $s){try{FoodGate::sql($s,'ai');throw new LogicException('Unsafe SQL accepted');}catch(RuntimeException $e){$checks++;}}$data=['name'=>'CDXFOOD11W1','edible_part'=>'100','energy'=>'123.45','create_by'=>'CDX','en_name'=>'CDXFOOD11W1'];$bind=[];$all=$data+['create_time'=>date('Y-m-d H:i:s')];foreach($all as $k=>$v)$bind[':data__'.$k]=['value'=>$v,'type'=>in_array($k,['edible_part','energy'],true)?1:2,'php_type'=>'string','ok'=>true];$sql='INSERT INTO `ydy_foods_composition` (`'.implode('`,`',array_keys($all)).'`) VALUES ('.implode(',',array_keys($bind)).')';FoodGate::$case=['allowed'=>['kind'=>'insert','data'=>$data]];FoodGate::execute($sql,$bind,null,'store');$checks++;foreach(['name','energy','extra','type','role']as $m){FoodGate::$dml=0;$b=$bind;$role='store';if($m==='name')$b[':data__name']['value']='NATURAL';if($m==='energy')$b[':data__energy']['value']=123.45;if($m==='extra')$b[':extra']=['value'=>'x','type'=>2,'php_type'=>'string','ok'=>true];if($m==='type')$b[':data__energy']['type']=2;if($m==='role')$role='ai';try{FoodGate::execute($sql,$b,null,$role);throw new LogicException('Typed scope mutation accepted');}catch(RuntimeException $e){$checks++;}}require __DIR__.'/Oracle.php';$d=foodOracle([['energy'=>12.34,'protein'=>'0.00','img'=>null,'category'=>0,'minute_sort'=>0,'reclassify'=>0]],[],'readById',2);if($d['data']['energy']!=='12.34'||$d['data']['protein']!=='0.00'||$d['data']['img']!==null)throw new RuntimeException('Independent full row oracle');$checks++;$h=fopen(__DIR__.'/private/puregate.json','xb');fwrite($h,json_encode(['checks'=>$checks,'DB'=>0]));fclose($h);chmod(__DIR__.'/private/puregate.json',0600);echo json_encode(['puregate_checks'=>$checks,'DB'=>0]),"\n";exit;}
if($mode==='cleanup'){$p=json_decode(file_get_contents(__DIR__.'/private/pid.json'),true);$cmd=(string)@file_get_contents('/proc/'.$p['pid'].'/cmdline');if($cmd!==''&&(strpos($cmd,__DIR__.'/index.php')===false||strpos($cmd,'127.0.0.1:'.$p['port'])===false))throw new RuntimeException('Own worker identity');$removed=[];$walk=static function($dir)use(&$walk,&$removed){if(!is_dir($dir))return;foreach(scandir($dir)as $n){if($n==='.'||$n==='..')continue;$f=$dir.'/'.$n;if(is_link($f))throw new RuntimeException('No symlink cleanup');if(is_dir($f)){$walk($f);rmdir($f);}else{$removed[]=['file'=>$f,'sha256'=>hash_file('sha256',$f)];unlink($f);}}};$walk(__DIR__.'/cache');foreach(['auth.json','current.json','lease.json']as $n){$f=__DIR__.'/private/'.$n;if(is_file($f)){$removed[]=['file'=>$n,'sha256'=>hash_file('sha256',$f)];unlink($f);}}if($cmd!=='')posix_kill($p['pid'],SIGTERM);usleep(300000);if(@fsockopen('127.0.0.1',$p['port'],$n,$e,0.3))throw new RuntimeException('Port open');$r=['own_worker'=>$p,'own_port_closed'=>true,'removed'=>$removed,'original_parent_alive'=>is_file('/proc/'.(getenv('FOOD_LANE')==='B'?10001:112175).'/cmdline'),'DB'=>0,'HTTP'=>0];$f=__DIR__.'/private/cleanup.json';$h=fopen($f,'xb');fwrite($h,json_encode($r,JSON_PRETTY_PRINT));fclose($h);chmod($f,0600);echo json_encode(['cleanup'=>true,'port_closed'=>true]),"\n";exit;}
require __DIR__.'/common.php';require __DIR__.'/Oracle.php';$mutable=static function($name,$v){file_put_contents(__DIR__.'/private/'.$name,json_encode($v,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_PRESERVE_ZERO_FRACTION));chmod(__DIR__.'/private/'.$name,0600);};
if($mode==='preflight'){$s=$source(null,true);if($s['own']!==[]||count($s['actor'])!==1||$s['actor'][0]['type']!==0)throw new RuntimeException('Fresh marker and original actor');$cat=array_column($s['categories'],null,'id');if(!isset($cat[1],$cat[19])||(int)$cat[1]['pid']!==0||(int)$cat[19]['pid']!==1)throw new RuntimeException('Existing category1/19');$t=$q('store','SELECT * FROM ydy_config WHERE config_key=? AND status=?',['tchef_sync_config',1]);require __DIR__.'/source/application/common/service/tchef/Config.php';$tc=count($t)===1?json_decode($t[0]['config_value'],true):null;$enabled=is_array($tc)&&\app\common\service\tchef\Config::valid($tc);if($enabled!==($lane==='B'))throw new RuntimeException('Real tchef state drift');$a=$q('store','SELECT config_key,config_value FROM ydy_config WHERE config_key=? AND status=?',['ai_sync_switch',1]);if(count($a)!==1||$a[0]['config_value']!=1)throw new RuntimeException('Real AI sync state');$meta=$lane==='B'?$q('store','SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY ORDINAL_POSITION',['ydy_foods_composition']):$q('store','SELECT * FROM USER_TAB_COLUMNS WHERE TABLE_NAME=? ORDER BY COLUMN_ID',['YDY_FOODS_COMPOSITION']);$tr=$lane==='B'?$q('store','SELECT * FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA=DATABASE() AND EVENT_OBJECT_TABLE=?',['ydy_foods_composition']):$q('store','SELECT * FROM USER_TRIGGERS WHERE TABLE_NAME=?',['YDY_FOODS_COMPOSITION']);if(count($meta)!==62||$tr!==[])throw new RuntimeException('Actual Food metadata/trigger scope');$save('baseline.json',$s);$save('preflight.json',['lane'=>$lane,'prior_reads'=>$lane==='B'?12:11,'real_tchef_enabled'=>$enabled,'real_ai_sync_enabled'=>true,'columns'=>$meta,'triggers'=>$tr,'source'=>$s,'observer'=>$GLOBALS['FOOD_OBSERVER']]);echo json_encode(['lane'=>$lane,'preflight'=>true,'marker0'=>true,'real_tchef_enabled'=>$enabled,'columns'=>62]),"\n";exit;}
if($mode==='auth'||$mode==='tap-proof'){$s=$source();$base=json_decode(file_get_contents(__DIR__.'/private/baseline.json'),true);$guard($base,$s);require __DIR__.'/init.php';$classes=['AIApi'=>(new ReflectionClass(\app\common\AIApi::class))->getFileName(),'FoodHook'=>(new ReflectionClass(\app\common\service\tchef\FoodHook::class))->getFileName(),'FoodController'=>(new ReflectionClass(\app\p\controller\Food::class))->getFileName()];foreach(['AIApi'=>'common/AIApi.php','FoodHook'=>'common/service/tchef/FoodHook.php','FoodController'=>'p/controller/Food.php']as $k=>$path)if($classes[$k]!==__DIR__.'/source/application/'.$path)throw new RuntimeException('Original application class affinity');$cfgClass=(new ReflectionClass(\app\common\service\tchef\Config::class))->getFileName();if($cfgClass!==__DIR__.($lane==='B'?'/TchefProcessConfig.php':'/source/application/common/service/tchef/Config.php'))throw new RuntimeException('Explicit only B config isolation');
 if($mode==='auth'){$token=(new \app\p\logic\Login())->userTokenSet($s['actor'][0]);if(FoodGate::$journal!==[])throw new RuntimeException('Auth unexpected SQL');$save('auth.json',['token'=>$token]);$save('auth-proof.json',['original_classes'=>$classes,'tchef_Config_class'=>$cfgClass,'source'=>$s,'observer'=>$GLOBALS['FOOD_OBSERVER'],'business_SQL'=>0]);echo json_encode(['lane'=>$lane,'auth'=>true,'SQL'=>0]),"\n";exit;}
 $proof=[];foreach(['store'=>\think\Db::connect(),'ai'=>get_ai_db()]as $role=>$conn){$rp=new ReflectionProperty(\think\db\Connection::class,'linkID');$rp->setAccessible(true);$pdo=$rp->getValue($conn);if(!($pdo instanceof FoodPDO)||$pdo->schema!==$role)throw new RuntimeException('Actual native PDO tap');$c=$conn->getConfig();$identity=$conn->query($lane==='B'?'SELECT DATABASE() AS db':"SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') AS db FROM DUAL");if($identity[0]['db']!==($role==='store'?$cfg['database']:$ai['database']))throw new RuntimeException('Actual database identity');$rows=$role==='store'?$conn->query('SELECT id,uuid FROM ydy_user WHERE id=:actor',['actor'=>[$lane==='B'?97260:2791,1]]):$conn->query('SELECT 1 AS marker FROM DUAL');$proof[$role]=['driver'=>get_class($conn),'pdo'=>get_class($pdo),'identity'=>$identity,'rows'=>$rows];}$save('tap-proof.json',['proof'=>$proof,'native'=>FoodGate::$journal,'source'=>$s,'observer'=>$GLOBALS['FOOD_OBSERVER'],'before_HTTP'=>true]);echo json_encode(['lane'=>$lane,'both_original_connections_proven'=>true,'native'=>count(FoodGate::$journal)]),"\n";exit;
}
if($mode==='finish'){$s=$source(null,true);$base=json_decode(file_get_contents(__DIR__.'/private/baseline.json'),true);if($s!==$base)throw new RuntimeException('Final whole scoped state not original');$save('final.json',['source'=>$s,'observer'=>$GLOBALS['FOOD_OBSERVER'],'baseline_exact'=>true]);echo json_encode(['lane'=>$lane,'final_exact'=>true]),"\n";exit;}
if($mode!=='step')throw new RuntimeException('Mode');$stage=(int)($argv[2]??0);if($stage<1||$stage>10)throw new RuntimeException('Only ten stages');$label=$lane==='B'&&$stage===1?'01-fixed':sprintf('%02d',$stage);if(is_file(__DIR__.'/private/sent-'.$label.'.json'))throw new RuntimeException('No request replay');if(!is_file(__DIR__.'/private/tap-proof.json'))throw new RuntimeException('Actual tap first');$base=json_decode(file_get_contents(__DIR__.'/private/baseline.json'),true);$owned=is_file(__DIR__.'/private/owned.json')?json_decode(file_get_contents(__DIR__.'/private/owned.json'),true):null;$id=$owned['id']??null;$previous=$lane==='B'&&$stage===2?'01-fixed':sprintf('%02d',$stage-1);$before=$stage===1?$source():json_decode(file_get_contents(__DIR__.'/private/wire-'.$previous.'.json'),true)['after'];$guard($base,$before);$row=$before['own'][0]??null;
$method=[1=>'add',2=>'readById',3=>'lists',4=>'update',5=>'readById',6=>'update',7=>'readById',8=>'delete',9=>'readById',10=>'lists'][$stage];$strings=['name'=>' CDXFOOD11W1 ','sub_name'=>' CDXFOOD11W1A ','edible_part'=>'100','energy'=>'123.45','protein'=>'12.34','fat'=>'5.67','carbohydrate'=>'23.45','dietary_fiber'=>'1.23','category'=>'1','minute_sort'=>'19','reclassify'=>'0'];$allowed=null;$params=[];
if($stage===1)$params=$strings;elseif($method==='lists')$params=['name'=>'CDXFOOD11W1','page'=>1,'pagesize'=>2];elseif(in_array($stage,[2,5,7,9],true))$params=['id'=>(int)$id];elseif($stage===4){$params=['id'=>(int)$id]+$strings;$params['edible_part']=0;}elseif($stage===6){if(!$row)throw new RuntimeException('Own row');usleep(2100000);$params=['id'=>(int)$id,'name'=>' CDXFOOD11W1-U ','sub_name'=>' CDXFOOD11W1AU ','edible_part'=>1,'energy'=>124.56,'protein'=>13.45,'fat'=>6.78,'carbohydrate'=>24.56,'dietary_fiber'=>2.34,'category'=>1,'minute_sort'=>19,'reclassify'=>0];}else{$params=['id'=>(string)$id];if(!$row||$row['id']!==$owned['id']||$row['name']!=='CDXFOOD11W1-U'||$row['sub_name']!=='CDXFOOD11W1AU'||(int)$row['store_id']!==10001||$before['own_dish_references']!==[])throw new RuntimeException('New own delete closure and reference0');$save('delete-lease.json',['created_journal'=>'owned.json','full_own_row'=>$row,'all_dish_references'=>$before['own_dish_references']]);}
if(in_array($stage,[1,6],true)){$data=$params;unset($data['id']);$data['name']=trim($data['name']);$data['sub_name']=trim($data['sub_name']);$data['category_two']=$data['minute_sort'];$data['category_three']=$data['reclassify'];$data['create_by']=(string)$before['actor'][0]['name'];$data['en_name']=$stage===1?'CDXFOOD11W1':'CDXFOOD11W1U';$allowed=['kind'=>$stage===1?'insert':'update','data'=>$data];if($stage===6)$allowed['id']=$id;}elseif($stage===8)$allowed=['kind'=>'delete','data'=>[],'id'=>$id];
$case=['label'=>$label,'stage'=>$stage,'method'=>$method,'path'=>'/p/food/'.$method,'params'=>$params,'allowed'=>$allowed,'own_id'=>$id];$mutable('current.json',$case);$mutable('lease.json',$before);$save('before-'.$label.'.json',['source'=>$before,'case'=>$case,'observer'=>$GLOBALS['FOOD_OBSERVER']]);$budget('HTTP',$lane==='B'?11:10);$save('sent-'.$label.'.json',['case'=>$case,'started'=>microtime(true)]);$auth=json_decode(file_get_contents(__DIR__.'/private/auth.json'),true);$headers=[];$c=curl_init('http://127.0.0.1:'.($lane==='B'?18995:18996).$case['path']);curl_setopt_array($c,[CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode($params,JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION),CURLOPT_RETURNTRANSFER=>true,CURLOPT_HTTPHEADER=>['Content-Type: application/json','token: '.$auth['token'],'X-CDX-CASE: '.$label],CURLOPT_CONNECTTIMEOUT=>5,CURLOPT_TIMEOUT=>60,CURLOPT_HEADERFUNCTION=>static function($c,$v)use(&$headers){$headers[]=$v;return strlen($v);}]);$body=curl_exec($c);$info=curl_getinfo($c);$error=curl_error($c);curl_close($c);$save('client-'.$label.'.json',['status'=>$info['http_code'],'headers'=>$headers,'body'=>$body,'error'=>$error,'duration'=>$info['total_time']]);usleep(150000);
$wire=json_decode((string)file_get_contents(__DIR__.'/private/wire-'.$label.'.json'),true);$response=json_decode((string)file_get_contents(__DIR__.'/private/response-'.$label.'.json'),true);if(!$wire||!$response||$body!==$wire['body']||$body!==$response['body']||$info['http_code']!==200||empty($wire['protected_equal']))throw new RuntimeException('Original response/guard failure');$after=$wire['after'];if($stage===1){if(count($after['own'])!==1)throw new RuntimeException('Exactly one created own row');$new=$after['own'][0];$ids=array_values(array_filter($wire['native'],static function($e){return ($e['layer']??'')==='PDO.lastInsertId';}));if(count($ids)!==1||(string)$ids[0]['value']!==(string)$new['id']||$new['name']!=='CDXFOOD11W1'||(int)$new['store_id']!==10001)throw new RuntimeException('Actual original generated PK/tenant');$owned=['id'=>$new['id'],'name'=>$new['name'],'sub_name'=>$new['sub_name'],'store_id'=>$new['store_id'],'full_created_row'=>$new,'journal_label'=>$label];$save('owned.json',$owned);$id=$new['id'];}$guard($base,$after);if($wire['DML_attempts']!==($allowed===null?0:1))throw new RuntimeException('Exact native DML count');foreach($wire['native']as $entry)if(isset($entry['sql'])&&preg_match('/^\s*(INSERT|UPDATE|DELETE)\b/i',$entry['sql'])&&($entry['affected']??null)!==1)throw new RuntimeException('Exact source write affected1');$expected=foodOracle($after['own'],$after['categories'],$method,$stage);$decoded=json_decode($body,true);if($decoded!==$expected)throw new RuntimeException('Independent full typed DTO mismatch');
$inputDifferences=[];if(in_array($stage,[1,6],true))foreach(['edible_part','energy','protein','fat','carbohydrate','dietary_fiber']as $k){$actual=$after['own'][0][$k];if((float)$actual!==(float)$params[$k])$inputDifferences[$k]=['input'=>$params[$k],'input_PHP_type'=>gettype($params[$k]),'stored'=>$actual,'stored_PHP_type'=>gettype($actual)];}if($stage===4&&$before!==$after)throw new RuntimeException('Invalid update whole row not unchanged');if($stage===8&&$after['own']!==[])throw new RuntimeException('Deletion not visible');$save('result-'.$label.'.json',['expected_full_DTO'=>$expected,'actual_full_DTO'=>$decoded,'full_DTO_exact'=>true,'input_storage_differences'=>$inputDifferences,'source_before'=>$before,'source_after'=>$after,'observer'=>$GLOBALS['FOOD_OBSERVER'],'native_DML'=>$wire['DML_attempts']]);echo json_encode(['lane'=>$lane,'stage'=>$stage,'HTTP'=>$info['http_code'],'code'=>$decoded['code'],'DTO_exact'=>true,'DML'=>$wire['DML_attempts'],'input_storage_differences'=>array_keys($inputDifferences)],JSON_UNESCAPED_UNICODE),"\n";
