<?php
declare(strict_types=1);
require __DIR__.'/common.php';$lane=getenv('SM7_LANE');$runtime=getenv('SM7_RUNTIME');$socket=@fsockopen('127.0.0.1',$lane==='B'?18411:18412,$n,$e,1);if($socket){fclose($socket);throw new RuntimeException('Assigned private port occupied');}
set_exception_handler(static function(Throwable $e):void{smSave('metadata-error-private.json',['class'=>get_class($e),'message'=>$e->getMessage()]);echo json_encode(['status'=>'metadata-error','class'=>get_class($e),'message_sha256'=>hash('sha256',$e->getMessage())]),PHP_EOL;exit(1);});
$requirements=[
 'POST /api/consume/dishes'=>['dishes'=>['id','uuid','name','price','file_path','unit','is_del','category'],'config_enum'=>['id','enum_key','enum_name','enum_type','is_delete','order']],
 'POST /api/consume/dishesRecognizeImgList'=>['dishes_recognize_img'=>['id','dishes_uuid','img_url','feature','is_delete'],'dishes'=>['uuid','is_del']],
 'POST /api/consume/orderList'=>['meal_order'=>['id','order_no','user_id','bind_time','meal_times','total_price','meal_number','pay_status','pay_time','pay_price','meal_date','equipment_code','source','order_status','cash','subsidy','gift','refund_amount','refund_status','cash_refund_amount','subsidy_refund_amount','gift_refund_amount','remain_balance','is_delete','restaurant_id'],'user'=>['id','nickname','name','mobile'],'equipment'=>['id','code','name','del_flag','restaurant_id'],'config'=>['config_key','config_value','status']],
 'POST /api/consume/card'=>['staff_card'=>['card_id','card_status','is_delete','staff_uuid'],'staff'=>['uuid','is_show','identity_number'],'user'=>['id','name','staff_uuid','ai_user_id','mobile','is_delete'],'staff_department'=>['staff_uuid','department_uuid'],'department'=>['uuid','puuid','name']],
 'GET /p/api/getFaceDataList'=>['staff'=>['id','uuid','name','mobile','create_time','is_show'],'hardware_img'=>['staff_uuid','is_del','uuid','head_img','create_time','head_img_url']],
 'POST /p/api/rotation'=>['nutrition_station'=>['code','uuid','interval_time'],'annex'=>['master_uuid','file_path','id'],'config'=>['config_key','config_value','status']],
];
$readMeta=static function(PDO $db,array $tables,string $prefix)use($lane):array{$out=[];foreach($tables as $table){$name=$prefix.$table;$out[$table]=smRows($db,$lane==='C'?'SELECT COLUMN_NAME,DATA_TYPE,DATA_PRECISION,DATA_SCALE,NULLABLE,DATA_LENGTH FROM USER_TAB_COLUMNS WHERE TABLE_NAME=? ORDER BY COLUMN_ID':'SELECT COLUMN_NAME,DATA_TYPE,COLUMN_TYPE,NUMERIC_PRECISION,NUMERIC_SCALE,DATETIME_PRECISION,IS_NULLABLE,CHARACTER_MAXIMUM_LENGTH FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY ORDINAL_POSITION',[$lane==='C'?strtoupper($name):$name]);}return $out;};
$tables=[];foreach($requirements as $requirement){$tables=array_merge($tables,array_keys($requirement));}$tables=array_values(array_unique($tables));$store=smPdo();$meta=$readMeta($store,$tables,'ydy_');$gates=[];foreach($requirements as $route=>$requirement){$missing=[];foreach($requirement as $table=>$columns){$actual=array_map('strtolower',array_column($meta[$table],'column_name'));foreach($columns as $col){if(!in_array($col,$actual,true)){$missing[]=$table.'.'.$col;}}}$gates[$route]=['store_columns_ready'=>$missing===[],'missing'=>$missing];}
$aiReady=false;$aiMeta=[];$aiError=null;try{
    $cfg=require getenv('SM7_PARENT').'/application/database.php';if($lane==='B'){define('APP_PATH','/workspace/zhct/zhctproject/store/application/');define('TP_ENV','local');define('BUSINESS','');$local=require APP_PATH.'database.php';$a=array_merge($cfg,$cfg['ai_zhct']);$expected=array_merge($local,$local['ai_zhct']);foreach(['hostname','database','username','password','hostport','prefix','charset'] as $key){$actual=$a[$key]??null;$want=$expected[$key]??null;if($key==='hostport'){if(!ctype_digit((string)$actual)||!ctype_digit((string)$want)||(int)$actual<1||(int)$actual>65535){throw new RuntimeException('Invalid effective AI port');}$actual=(string)(int)$actual;$want=(string)(int)$want;}if($actual!==$want){throw new RuntimeException('Not code local AI customer connection');}}$dsn='mysql:host='.$a['hostname'].';port='.(int)$a['hostport'].';dbname='.$a['database'].';charset='.($a['charset']??'utf8');$options=[PDO::ATTR_STRINGIFY_FETCHES=>false,PDO::ATTR_EMULATE_PREPARES=>false];}
    else{$a=['hostname'=>getenv('POC_AI_HOST'),'hostport'=>getenv('POC_AI_PORT'),'database'=>getenv('POC_AI_SCHEMA'),'username'=>getenv('POC_AI_USER'),'password'=>getenv('POC_AI_PASSWORD'),'prefix'=>'yoshop_'];if($a['hostname']!=='127.0.0.1'||$a['hostport']!=='5238'||$a['database']!=='AIZHCT_APP'||$a['username']!=='AIZHCT_APP'||$a['password']===''){throw new RuntimeException('Reviewed AI DM environment identity missing');}$dsn='dm:host=127.0.0.1;port=5238;schema=AIZHCT_APP';$options=[];}
    $ai=new PDO($dsn,$a['username'],$a['password'],$options+[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_CASE=>PDO::CASE_LOWER]);if($lane==='B'&&(strpos($ai->query('SELECT VERSION()')->fetchColumn(),'5.6.')!==0||$ai->query('SELECT DATABASE()')->fetchColumn()!==$a['database'])){throw new RuntimeException('Effective local AI identity mismatch');}if($lane==='C'&&$ai->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn()!=='AIZHCT_APP'){throw new RuntimeException('Effective AI DM schema mismatch');}
    $aiMeta=$readMeta($ai,['user','user_subsidy'],'yoshop_');$needed=['user'=>['user_id','balance','gift_balance','is_delete'],'user_subsidy'=>['user_id','money','is_delete','expiration_start_time','expiration_end_time']];$missing=[];foreach($needed as $table=>$cols){$actual=array_map('strtolower',array_column($aiMeta[$table],'column_name'));foreach($cols as $col){if(!in_array($col,$actual,true)){$missing[]=$table.'.'.$col;}}}$aiReady=$missing===[];$gates['POST /api/consume/card']['ai_missing']=$missing;
}catch(Throwable $e){$aiError=['class'=>get_class($e),'message_sha256'=>hash('sha256',$e->getMessage())];smSave('ai-metadata-error-private.json',['class'=>get_class($e),'message'=>$e->getMessage()]);}
$gates['POST /api/consume/card']['ai_connection_and_columns_ready']=$aiReady;$gates['POST /api/consume/card']['ai_error']=$aiError;
smSave('metadata-private.json',['lane'=>$lane,'store'=>$meta,'ai'=>$aiMeta,'gates'=>$gates,'assigned_port_was_empty'=>true,'business_rows_selected'=>0,'database_dml_ddl'=>0]);echo json_encode(['lane'=>$lane,'gates'=>$gates,'assigned_port_was_empty'=>true,'business_rows_selected'=>0,'database_dml_ddl'=>0]),PHP_EOL;
