<?php
declare(strict_types=1);$lane=getenv('INV_LANE');$dm=getenv('POC_DIALECT')==='dm';$runtime=__DIR__.'/private';if(!is_dir($runtime))mkdir($runtime,0700);chmod($runtime,0700);$dsn=$dm?'dm:host=127.0.0.1;port=5238;schema=AIZHCT_APP':'mysql:host='.getenv('POC_AI_HOST').';port='.getenv('POC_AI_PORT').';dbname='.getenv('POC_AI_SCHEMA').';charset='.getenv('POC_AI_CHARSET');$pdo=new PDO($dsn,getenv('POC_AI_USER'),getenv('POC_AI_PASSWORD'),[PDO::ATTR_CASE=>PDO::CASE_LOWER,PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_ORACLE_NULLS=>PDO::NULL_NATURAL,PDO::ATTR_STRINGIFY_FETCHES=>false,PDO::ATTR_EMULATE_PREPARES=>false]);$events=[];
$q=static function($sql,$params=[])use($pdo,&$events,$runtime){if(!preg_match('/^SELECT\b/',$sql)||preg_match('/;|\b(?:INSERT|UPDATE|DELETE|ALTER|DROP|CREATE|INTO|CALL)\b/i',$sql))throw new RuntimeException('Preflight SELECT only');$s=$pdo->prepare($sql);$b=[];foreach(array_values($params) as $i=>$v){$s->bindValue($i+1,(string)$v,PDO::PARAM_STR);$b[]=['position'=>$i+1,'value'=>(string)$v,'pdo_type'=>PDO::PARAM_STR];}$s->execute();$rows=$s->fetchAll(PDO::FETCH_ASSOC);foreach($rows as &$r)foreach($r as &$v)if(is_resource($v))$v=stream_get_contents($v);unset($r,$v);$event=['queryString'=>$s->queryString,'bindValue'=>$b,'rowCount'=>$s->rowCount(),'rows'=>$rows];$events[]=$event;file_put_contents($runtime.'/probe.jsonl',json_encode($event,JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION)."\n",FILE_APPEND|LOCK_EX);chmod($runtime.'/probe.jsonl',0600);return $rows;};
$identity=$q($dm?"SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') schema_name FROM DUAL":'SELECT DATABASE() schema_name,VERSION() version,@@SESSION.sql_mode sql_mode,@@character_set_connection connection_charset');if($identity[0]['schema_name']!==($dm?'AIZHCT_APP':getenv('POC_AI_SCHEMA'))||(!$dm&&strpos($identity[0]['version'],'5.6.')!==0))throw new RuntimeException('Approved DB identity');
$schema=[];foreach(['nutrition_meals','nutrition_lack','staff','store_user','config_enum'] as $t){$name='yoshop_'.$t;$u=strtoupper($name);$cols=$q($dm?'SELECT COLUMN_NAME,DATA_TYPE,NULLABLE,DATA_DEFAULT,DATA_LENGTH,DATA_PRECISION,DATA_SCALE FROM USER_TAB_COLUMNS WHERE TABLE_NAME=? ORDER BY COLUMN_ID':'SELECT COLUMN_NAME,DATA_TYPE,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE,EXTRA FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY ORDINAL_POSITION',[$dm?$u:$name]);$tr=$q($dm?'SELECT * FROM USER_TRIGGERS WHERE TABLE_NAME=?':'SELECT TRIGGER_NAME,EVENT_MANIPULATION,ACTION_TIMING,ACTION_STATEMENT FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA=DATABASE() AND EVENT_OBJECT_TABLE=?',[$dm?$u:$name]);$fk=$q($dm?"SELECT CONSTRAINT_NAME,TABLE_NAME,R_CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE CONSTRAINT_TYPE='R' AND (TABLE_NAME=? OR R_CONSTRAINT_NAME IN (SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS WHERE TABLE_NAME=?))":'SELECT TABLE_NAME,CONSTRAINT_NAME,COLUMN_NAME,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL AND (TABLE_NAME=? OR REFERENCED_TABLE_NAME=?)',[$dm?$u:$name,$dm?$u:$name]);$schema[$t]=['columns'=>$cols,'triggers'=>$tr,'FK'=>$fk];if($dm)$schema[$t]['DDL']=$q("SELECT DBMS_METADATA.GET_DDL('TABLE',?,'AIZHCT_APP') ddl FROM DUAL",[$u]);}
$staff=$lane==='B'?[46334,46335]:[1851,1852];$operators=$lane==='B'?[10074,10075]:[10010,10011];$tenants=[2147001111,2147001112];$ownStaff=$q('SELECT id,user_id,store_id,name,create_by,is_delete FROM yoshop_staff WHERE id IN (?,?) AND store_id IN (?,?) ORDER BY id',array_merge($staff,$tenants));$ownOperators=$q('SELECT store_user_id,store_id,user_name,real_name,is_super,is_delete FROM yoshop_store_user WHERE store_user_id IN (?,?) AND store_id IN (?,?) ORDER BY store_user_id',array_merge($operators,$tenants));if(count($ownStaff)!==2||count($ownOperators)!==2)throw new RuntimeException('Retained own principal counts');foreach($ownOperators as $i=>$o)if((int)$o['store_user_id']!==$operators[$i]||(int)$o['store_id']!==$tenants[$i]||(int)$o['is_super']!==1||(int)$o['is_delete']!==0||strpos($o['user_name'],'cdxop11f64c_')!==0||$ownStaff[$i]['create_by']!=='CDXRR11A8F4')throw new RuntimeException('Own operator/staff identity mismatch');
$old=[];foreach(['nutrition_meals','nutrition_lack'] as $t)$old[$t]=$q('SELECT * FROM yoshop_'.$t.' WHERE store_id IN (?,?) ORDER BY id',$tenants);
$new=[];foreach(['nutrition_meals','nutrition_lack'] as $t)$new[$t]=$q('SELECT COUNT(*) n FROM yoshop_'.$t.' WHERE store_id=? AND staff_id=? AND user_id=? AND set_date=?',[2147001111,$staff[0],$operators[0],'2097-11-11']);foreach($new as $c)if((int)$c[0]['n']!==0)throw new RuntimeException('Fresh survey date collision');
$dictionary=$q('SELECT * FROM yoshop_config_enum WHERE enum_type IN (6,7,8,9,10,11) AND is_delete=0 ORDER BY enum_type,'.($dm?'"ORDER"':'`order`'));
$port=$lane==='B'?18911:18912;$s=@fsockopen('127.0.0.1',$port,$e,$m,1);$collision=$s!==false;if($s)fclose($s);$raw=['lane'=>$lane,'HTTP'=>0,'DML'=>0,'DDL'=>0,'identity'=>$identity,'schema'=>$schema,'staff'=>$ownStaff,'operators'=>$ownOperators,'existing_survey_rows'=>$old,'fresh_scope_counts'=>$new,'dictionary'=>$dictionary,'port'=>$port,'port_collision'=>$collision,'events'=>$events];$json=json_encode($raw,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRESERVE_ZERO_FRACTION);if($json===false)throw new RuntimeException('Raw encoding');$file=$runtime.'/probe-'.$lane.'.json';if(file_exists($file))throw new RuntimeException('Do not overwrite original preflight');file_put_contents($file,$json);chmod($file,0600);$out=['lane'=>$lane,'HTTP'=>0,'DML'=>0,'DDL'=>0,'SELECT'=>count($events),'original_meals'=>count($old['nutrition_meals']),'original_lack'=>count($old['nutrition_lack']),'dictionary_rows'=>count($dictionary),'fresh_date_collision'=>0,'port_collision'=>$collision,'all_FK_trigger_zero'=>count(array_filter($schema,static function($s){return $s['FK']||$s['triggers'];}))===0,'raw_bytes'=>strlen($json),'raw_sha256'=>hash('sha256',$json)];file_put_contents(__DIR__.'/probe-'.$lane.'.json',json_encode($out,JSON_PRETTY_PRINT));echo json_encode($out),"\n";
