<?php
declare(strict_types=1);require __DIR__.'/WeightContract.php';
final class CoreGate extends WeightContract{
 public static function writer(){return false;}
 public static function known($db,$table){parent::known($db,$table);$p=json_decode(file_get_contents(__DIR__.'/execution-plan.json'),true);ck(in_array(strtolower($table),$p['metadata_tables'][$db],true),'Only source-reviewed metadata names');}
 public static function kind($db,$sql){
  $p=preg_replace("/'(?:''|\\\\.|[^'\\\\])*'/s",'?',$sql);
  ck(!preg_match('/;|--|\/\*|\*\/|#|\b(?:INSERT|UPDATE|DELETE|REPLACE|MERGE|CREATE|ALTER|DROP|TRUNCATE|GRANT|REVOKE|OUTFILE|DUMPFILE|LOAD|EXEC|EXECUTE|SLEEP|BENCHMARK|UTL_HTTP|NEXTVAL|INTO)\b/i',$p),'Pure read noDMLDDL/lock/external SQL');
  if($sql===self::COLUMNS||$sql===self::PRIMARY)return 'metadata_SELECT';
  if(preg_match('/^SHOW FULL COLUMNS FROM \x60([A-Za-z_][A-Za-z0-9_]*)\x60$/D',$sql,$m)){self::known($db,$m[1]);return 'metadata_SHOW';}
  if($sql==='CALL SP_TABLEDEF(?, ?)'&&self::$meta)return 'metadata_CALL';
  if(in_array($sql,["SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') schema_name FROM DUAL",'SELECT DATABASE() schema_name,VERSION() version'],true)){ck(self::$scenario==='CONSTRUCTOR_WARM','Only warm live identity');return 'identity_SELECT';}
  ck(!preg_match('/\bUSER_(?:TAB_COLUMNS|CONSTRAINTS|CONS_COLUMNS|TABLES)\b/i',$sql),'Only exact catalog shapes');ck(preg_match('/^\s*SELECT\b/i',$sql),'Only SELECT');preg_match_all('/\b(yoshop|ydy)_([a-z0-9_]+)/i',$sql,$m,PREG_SET_ORDER);ck(count($m)>0,'Explicit business table');
  $allowed=$db==='AI'?['user','staff','user_oauth','store','store_setting','upload_file','sign_action','sign_address']:['user','staff','measurement_session','health_record'];
  foreach($m as $t)ck(strtolower($t[1])===($db==='AI'?'yoshop':'ydy')&&in_array(strtolower($t[2]),$allowed,true),'Exact reviewed table only');return 'SELECT';
 }
 public static function plan($db,$sql,$bind){
  global $runtime;$kind=self::kind($db,$sql);$values=array_values(array_map(static function($x){return is_array($x)?$x[0]:$x;},$bind));
  if($kind==='metadata_SELECT'){ck(count($values)===1,'One table catalog bind');self::known($db,$values[0]);return;}
  if($kind==='metadata_SHOW'){ck($values===[],'SHOW0bind');return;}
  if($kind==='metadata_CALL'){ck(count($values)===2&&$values[0]===strtoupper((string)getenv('POC_'.$db.'_SCHEMA')),'Exact schema');self::known($db,$values[1]);return;}
  if($kind==='identity_SELECT'){ck($values===[],'Identity0bind');return;}
  $scope=json_decode(file_get_contents($runtime.'/resolved-scope.json'),true);$a=self::a();$flat=array_map('strval',$values);$scenario=preg_replace('/_RETEST$/D','',self::$scenario);$rank=in_array($scenario,['R3_RANK_CURRENT','R4_RANK_BY_DATE'],true);
  if($db==='AI'){
   if(preg_match('/\byoshop_(?:user|staff|user_oauth)\b/i',$sql))ck(in_array((string)$a['user_id'],$flat,true),'Own marked actor only');
   if(preg_match('/\byoshop_store(?:_setting)?\b/i',$sql))ck(in_array('10001',$flat,true),'Own tenant config');
   if(preg_match('/\byoshop_(?:sign_action|sign_address)\b/i',$sql))ck($scenario==='R5_SIGN_DETAIL'&&$scope['sign_id']>0&&in_array((string)$scope['sign_id'],$flat,true),'Chosen action relation only');
   if(stripos($sql,'yoshop_upload_file')!==false){$lease=json_decode(file_get_contents($runtime.'/tenant-file-lease.json'),true);$clean=str_replace([chr(96),'"'],'',$sql);ck(preg_match('/(?:\b\w+\.)?file_id\s*(?:=\s*(:\w+)|IN\s*\(([^)]+)\))/i',$clean,$m),'Exact file relation');$tokens=isset($m[2])&&$m[2]!==''?explode(',',$m[2]):[$m[1]];foreach($tokens as $t){$k=ltrim(trim($t),':');ck(isset($bind[$k]),'Named file bind');$v=$bind[$k];ck(in_array((string)(is_array($v)?$v[0]:$v),$lease['allowed_file_ids'],true),'Exact related file IDs');}ck(in_array('10001',$flat,true),'File source tenant');}return;
  }
  if(stripos($sql,'ydy_user')!==false){ck(in_array((string)$a['user_id'],$flat,true),'Only linked Auth user');return;}
  $sessions=stripos($sql,'ydy_measurement_session')!==false;$health=stripos($sql,'ydy_health_record')!==false;$staff=stripos($sql,'ydy_staff')!==false;if($staff)ck($rank,'Staff only actual rank JOIN');
  if($sessions){
   // Original group count inlines values; allow only this complete original SQL shape, never arbitrary literal SQL.
   if($bind===[]&&$scenario==='R3_RANK_CURRENT'&&stripos($sql,'HAVING')!==false){
    $normal=preg_replace('/\s+/',' ',trim(str_replace([chr(96),'"'],'',$sql)));
    $expected="SELECT COUNT(*) AS think_count FROM ( SELECT r.ai_user_id, SUM(r.value) AS v,count(*) AS think_count FROM ydy_health_record r INNER JOIN ydy_measurement_session s ON r.session_id=s.session_id WHERE s.vendor = 'yingjiduo' AND s.is_valid = '1' AND r.metric_code = 'activity_duration' AND r.start_time BETWEEN '2026-01-01 00:00:00' AND '2026-12-31 23:59:59' AND s.device_type = 'treadmill' GROUP BY r.ai_user_id HAVING v > 0 ) _group_count_";
    $normal=preg_replace('/ (?:LIMIT 1|FETCH FIRST 1 ROWS ONLY)$/D','',$normal);
    ck($scope['devices']===['treadmill']&&$normal===$expected,'Only exact original literal group count, frozen ownvalue0');
    $flat=['yingjiduo','1','activity_duration','2026-01-01 00:00:00','2026-12-31 23:59:59','treadmill'];
   }
   ck(in_array('yingjiduo',$flat,true),'Only original vendor');foreach($scope['devices'] as $d)ck(in_array($d,$flat,true),'Only device group');
   if(!$rank||$scenario==='R3_RANK_CURRENT'&&stripos($sql,'having')===false)ck(in_array((string)$a['user_id'],$flat,true),'Only own sports/current');
   if($rank){$range=$scenario==='R4_RANK_BY_DATE'?[$scope['day'].' 00:00:00',$scope['day'].' 23:59:59']:['2026-01-01 00:00:00','2026-12-31 23:59:59'];foreach($range as $date)ck(in_array($date,$flat,true),'Frozen exact source date range');ck(in_array('activity_duration',$flat,true),'Original metric');}
  }elseif($health){ck(count($flat)>0&&count(array_diff($flat,array_map('strval',$scope['own_session_ids'])))===0,'Only own real session IDs');}else ck(false,'No other secondary read');
 }
}
