<?php
declare(strict_types=1);
$lane=getenv('CATEGORY_LANE');$dm=getenv('POC_DIALECT')==='dm';if(!in_array($lane,['B','C'],true))exit(78);
$db=new PDO($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=utf8',getenv('POC_AI_USER'),getenv('POC_AI_PASSWORD'),[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_CASE=>PDO::CASE_LOWER]);
$query=static function(string $sql,array $args=[])use($db):array{if(!preg_match('/^SELECT\b/i',$sql))throw new RuntimeException('SELECT only preflight');$s=$db->prepare($sql);$s->execute($args);$r=[];while($row=$s->fetch(PDO::FETCH_ASSOC)){$row=array_change_key_case($row,CASE_LOWER);foreach($row as &$v)if(is_resource($v))$v=stream_get_contents($v);unset($v);$r[]=$row;if(count($r)>2000)throw new RuntimeException('Small-table preflight cap');}return $r;};
$check=static function(bool $ok,string $why):void{if(!$ok)throw new RuntimeException($why);};$report=['lane'=>$lane,'business_writes'=>0,'ddl'=>0,'http_requests'=>0,'tables'=>[]];
try{if($dm)$check($db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn()==='AIZHCT_APP'&&getenv('POC_AI_HOST')==='127.0.0.1'&&getenv('POC_AI_PORT')==='5238','DM identity');else $check($db->query('SELECT DATABASE()')->fetchColumn()===getenv('POC_AI_SCHEMA')&&strpos((string)$db->query('SELECT VERSION()')->fetchColumn(),'5.6.')===0,'Code local MySQL identity');
 foreach(['store','payment_template','payment'] as $table){$name='yoshop_'.$table;$upper=strtoupper($name);$meta=$dm?$query('SELECT COLUMN_NAME,DATA_TYPE,DATA_LENGTH,DATA_PRECISION,DATA_SCALE,NULLABLE,DATA_DEFAULT,CHAR_LENGTH,CHAR_USED FROM USER_TAB_COLUMNS WHERE TABLE_NAME=? ORDER BY COLUMN_ID',[$upper]):$query('SELECT COLUMN_NAME,COLUMN_TYPE,DATA_TYPE,IS_NULLABLE,COLUMN_DEFAULT,EXTRA,CHARACTER_SET_NAME,COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY ORDINAL_POSITION',[$name]);$check($meta!==[],'Table metadata exists');$trigger=$dm?$query('SELECT TRIGGER_NAME,STATUS,TRIGGERING_EVENT FROM USER_TRIGGERS WHERE TABLE_NAME=?',[$upper]):$query('SELECT TRIGGER_NAME,EVENT_MANIPULATION FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA=DATABASE() AND EVENT_OBJECT_TABLE=?',[$name]);$constraints=$dm?$query('SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE,R_CONSTRAINT_NAME,SEARCH_CONDITION FROM USER_CONSTRAINTS WHERE TABLE_NAME=? ORDER BY CONSTRAINT_NAME',[$upper]):$query('SELECT CONSTRAINT_NAME,COLUMN_NAME,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY CONSTRAINT_NAME,ORDINAL_POSITION',[$name]);$indexes=$dm?$query('SELECT i.INDEX_NAME,i.UNIQUENESS,c.COLUMN_NAME,c.COLUMN_POSITION FROM USER_INDEXES i JOIN USER_IND_COLUMNS c ON i.INDEX_NAME=c.INDEX_NAME WHERE i.TABLE_NAME=? ORDER BY i.INDEX_NAME,c.COLUMN_POSITION',[$upper]):$query('SELECT INDEX_NAME,NON_UNIQUE,SEQ_IN_INDEX,COLUMN_NAME FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY INDEX_NAME,SEQ_IN_INDEX',[$name]);$report['tables'][$table]=['columns'=>$meta,'triggers'=>$trigger,'constraints'=>$constraints,'indexes'=>$indexes];$check($trigger===[],'No unknown trigger side effects');}
 $collision=[];foreach([2147000701,2147000702] as $tenant)foreach(['store','payment_template','payment'] as $table)$collision[$tenant][$table]=(int)$query('SELECT COUNT(*) AS N FROM yoshop_'.$table.' WHERE store_id=?',[$tenant])[0]['n'];$report['tenant_collisions']=$collision;foreach($collision as $tables)foreach($tables as $n)$check($n===0,'New synthetic tenant must have zero collision');
 $report['source_snapshots']=[];foreach(['payment_template'=>'template_id','payment'=>'payment_id'] as $table=>$pk){$rows=$query('SELECT * FROM yoshop_'.$table.' ORDER BY '.$pk);$report['source_snapshots'][$table]=['rows'=>count($rows),'sha256'=>hash('sha256',serialize($rows))];}
 $report['connection_charset_from_code']=getenv('POC_AI_CHARSET')?:'utf8';$report['safe_preflight']=true;$report['failure']=null;
}catch(Throwable $e){$report['safe_preflight']=false;$report['failure']=['class'=>get_class($e),'message'=>$e->getMessage()];}
file_put_contents((string)getenv('CATEGORY_RUNTIME').'/preflight-private.json',json_encode($report,JSON_PRETTY_PRINT));chmod((string)getenv('CATEGORY_RUNTIME').'/preflight-private.json',0600);echo json_encode($report),"\n";exit($report['safe_preflight']?0:2);
