<?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'=>'CDXFOOD11W2','edible_part'=>'100','energy'=>'123.45','create_by'=>'CDX','en_name'=>'CDXFOOD11W2'];$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;}
