<?php
require __DIR__.'/base-run-prefix.php';
require __DIR__.'/common.php';require __DIR__.'/Oracle.php';$mutable=static function($n,$v){file_put_contents(__DIR__.'/private/'.$n,json_encode($v,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_PRESERVE_ZERO_FRACTION));chmod(__DIR__.'/private/'.$n,0600);};
if($mode==='preflight'){$s=$batch();if($s['own']!==[]||count($s['actor'])!==1||$s['actor'][0]['type']!==0)throw new RuntimeException('New marker0 and original actor');$cats=array_column($s['categories'],null,'id');if(!isset($cats[1],$cats[19])||(int)$cats[1]['pid']!==0||(int)$cats[19]['pid']!==1)throw new RuntimeException('Original category1/19 relation');$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 enabled/failclosed 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('Original AI switch');$cols=$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']);require __DIR__.'/schema-helper.php';$original=json_decode(file_get_contents(__DIR__.'/private/schema-baseline.json'),true)['metadata'];fd2_equal($cols,fd2_expected_columns($original['columns'],$lane==='C'),'Actual62 complete metadata expected source or Root date0');if($lane==='B'){fd2_need($tr===[],'B original trigger0');}else{fd2_need(count($tr)===1&&$tr[0]['trigger_name']==='TRG_YDY_FOODS_COMPOSITION_UT'&&$tr[0]['status']==='Y'&&$tr[0]['triggering_type']==='BEFORE ROW'&&$tr[0]['triggering_event']==='UPDATE','Root actual sole own trigger Y BEFORE ROW UPDATE');fd2_trigger($tr[0]['trigger_body'],file_get_contents(__DIR__.'/create-food-trigger.sql'));}$save('baseline.json',$s);$save('preflight.json',['source'=>$s,'columns'=>$cols,'triggers'=>$tr,'real_Tchef_enabled'=>$enabled,'real_AI_enabled'=>true,'observer'=>$GLOBALS['FOOD_OBSERVER'],'Root_schema46_separate_receipt'=>true]);echo json_encode(['lane'=>$lane,'new_marker0'=>true,'source62_and_schema'=>true,'observer'=>count($GLOBALS['FOOD_OBSERVER'])]),"\n";exit;}
$base=json_decode(file_get_contents(__DIR__.'/private/baseline.json'),true);
if($mode==='auth'||$mode==='tap-proof'){require __DIR__.'/init.php';if($mode==='auth'){$actor=$q('store','SELECT * FROM ydy_user WHERE id=?',[$lane==='B'?97260:2791]);if($actor!==$base['actor'])throw new RuntimeException('Fresh original actor full row');$token=(new \app\p\logic\Login())->userTokenSet($actor[0]);if(FoodGate::$journal!==[])throw new RuntimeException('Auth unexpected SQL');$save('auth.json',['token'=>$token]);$save('auth-proof.json',['source_actor'=>$actor,'observer'=>$GLOBALS['FOOD_OBSERVER'],'business_SQL'=>0,'new_cache'=>true]);echo json_encode(['lane'=>$lane,'new_Auth'=>true,'business_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 both PDO/Driver tap');$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('Exact actual DB 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,'before_INSERT'=>true]);echo json_encode(['lane'=>$lane,'both_actual_taps'=>true,'native'=>count(FoodGate::$journal)]),"\n";exit;}
if($mode==='finish'){$own=json_decode(file_get_contents(__DIR__.'/private/owned.json'),true);$s=$batch($own['id']);if($s!==$base)throw new RuntimeException('Final full batch original natural closure drift');$save('final.json',['source'=>$s,'baseline_exact'=>true,'observer'=>$GLOBALS['FOOD_OBSERVER'],'large_hash_only_batch_start_end'=>true]);echo json_encode(['lane'=>$lane,'batch_final_exact'=>true]),"\n";exit;}
if($mode!=='step')throw new RuntimeException('Mode');$n=(int)($argv[2]??0);if($n<1||$n>8)throw new RuntimeException('Only8 steps');$spec=$plan['cases'][$n-1];$label=$spec['label'];if(is_file(__DIR__.'/private/sent-'.$label.'.json'))throw new RuntimeException('No HTTP replay');$owned=is_file(__DIR__.'/private/owned.json')?json_decode(file_get_contents(__DIR__.'/private/owned.json'),true):null;$id=$owned['id']??null;$before=$n===1?['own'=>[],'categories'=>array_values(array_filter($base['categories'],static function($r){return in_array((int)$r['id'],[1,19],true);}))]:json_decode(file_get_contents(__DIR__.'/private/wire-F0'.($n-1).'.json'),true)['after'];$row=$before['own'][0]??null;
$params=$spec['params']??$spec['params_template'];if(isset($params['id'])){if($id===null)throw new RuntimeException('Must use newly journaled own PK');$params['id']=$params['id']==='OWN_PK_AS_STRING'?(string)$id:(int)$id;}$stage=$spec['original_stage'];$method=basename($spec['path']);$allowed=null;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)$base['actor'][0]['name'];$data['en_name']=$stage===1?'CDXFOOD11W2':'CDXFOOD11W2U';$allowed=['kind'=>$stage===1?'insert':'update','data'=>$data];if($stage===6)$allowed['id']=$id;}elseif($stage===8){if(!$row||$row['id']!==$owned['id']||$row['name']!=='CDXFOOD11W2-U'||$row['sub_name']!=='CDXFOOD11W2AU'||(int)$row['store_id']!==10001)throw new RuntimeException('Exact new own delete identity');$refs=$q('store','SELECT * FROM ydy_dish WHERE composition_id=? ORDER BY id',[(int)$id]);if($refs!==[])throw new RuntimeException('Own delete references must0');$save('delete-lease.json',['created_journal'=>'owned.json','full_own62'=>$row,'references'=>$refs]);$allowed=['kind'=>'delete','id'=>$id,'data'=>[]];}
if($stage===6){usleep(1100000);$clock=$q('store','SELECT CURRENT_TIMESTAMP(0) AS clock FROM DUAL');$v=$clock[0]['clock']??null;if(!is_string($v)||strtotime(substr($v,0,19))<=strtotime($row['update_time']))throw new RuntimeException('Once1100ms+actualDB clock must cross old seconds before UPDATE');$save('clock-F04.json',['original_native'=>$clock,'old_update_time'=>$row['update_time'],'observer'=>$GLOBALS['FOOD_OBSERVER'],'sleep_microseconds'=>1100000]);}
$case=['label'=>$label,'sequence'=>$n,'stage'=>$stage,'method'=>$method,'path'=>$spec['path'],'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',8);$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'?18997:18998).$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 wire/response/guard failure; no retry');$after=$wire['after'];if($stage===1){if(count($after['own'])!==1)throw new RuntimeException('Exactly1 new marked Food');$new=$after['own'][0];$last=array_values(array_filter($wire['native'],static function($e){return ($e['layer']??'')==='PDO.lastInsertId';}));if(count($last)!==1||(string)$last[0]['value']!==(string)$new['id']||$new['name']!=='CDXFOOD11W2'||(int)$new['store_id']!==10001)throw new RuntimeException('Original INSERT lastID/full row identity');$save('owned.json',['id'=>$new['id'],'name'=>$new['name'],'sub_name'=>$new['sub_name'],'store_id'=>$new['store_id'],'full_created62'=>$new,'journal_label'=>$label]);}
if(in_array($stage,[1,6],true))foreach(['edible_part','energy','protein','fat','carbohydrate','dietary_fiber']as $k)if((float)$after['own'][0][$k] !== (float)$params[$k])throw new RuntimeException('Original input numeric storage mismatch');if($wire['DML_attempts']!==($allowed===null?0:1))throw new RuntimeException('Exact expected Food DML');foreach($wire['native']as $e)if(isset($e['sql'])&&preg_match('/^\s*(INSERT|UPDATE|DELETE)\b/i',$e['sql'])&&($e['affected']??null)!==1)throw new RuntimeException('Original native affected1');$actual=json_decode($body,true);$expected=foodOracle($after['own'],$after['categories'],$method,$stage);if($actual!==$expected)throw new RuntimeException('Independent complete typed Food DTO');foreach($after['own']as $r)foreach(['create_time','update_time']as $k)if(!is_string($r[$k])||!preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/D',$r[$k]))throw new RuntimeException('Actual date0 must remain raw seconds, no stripping');if($stage===6&&strtotime($after['own'][0]['update_time'])<=strtotime($row['update_time']))throw new RuntimeException('Physical automatic UPDATE_TIME did not advance');$save('result-'.$label.'.json',['actual_full_DTO'=>$actual,'expected_full_DTO'=>$expected,'full_DTO_exact'=>true,'physical_before'=>$before,'physical_after'=>$after,'native_DML'=>$wire['DML_attempts'],'observer'=>$GLOBALS['FOOD_OBSERVER'],'actual_dates_untouched'=>true]);echo json_encode(['lane'=>$lane,'label'=>$label,'HTTP'=>$info['http_code'],'code'=>$actual['code'],'full_DTO'=>true,'DML'=>$wire['DML_attempts'],'native'=>count($wire['native'])]),"\n";
