<?php
declare(strict_types=1);date_default_timezone_set('Asia/Shanghai');
$lane=getenv('COMMENT_LANE');$dm=getenv('POC_DIALECT')==='dm';$root=getenv('COMMENT_ROOT');$runtime=getenv('COMMENT_RUNTIME');$base=getenv('COMMENT_BASE');$marker='CDXLF11F86A';$tenants=['store'=>2147001111,'terminal'=>2147001112];
$check=static function($ok,$why){if(!$ok)throw new RuntimeException($why);};
$persist=static function($name,$value)use($runtime){if(!is_dir($runtime))mkdir($runtime,0700);$json=json_encode($value,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES|JSON_PRESERVE_ZERO_FRACTION);if($json===false)throw new RuntimeException('Evidence JSON encoding failed: '.json_last_error_msg());file_put_contents($runtime.'/'.$name,$json);chmod($runtime.'/'.$name,0600);};
$connect=static function()use($dm){return 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='.getenv('POC_AI_CHARSET'),getenv('POC_AI_USER'),getenv('POC_AI_PASSWORD'),[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_CASE=>PDO::CASE_LOWER]);};
$query=static function($pdo,$sql,$params=[])use($runtime){if(!preg_match('/^\s*SELECT\b/i',$sql)||preg_match('/\b(INTO|CALL|OUTFILE|FOR\s+UPDATE)\b/i',$sql))throw new RuntimeException('Independent oracle SELECT only');$s=$pdo->prepare($sql);$s->execute($params);$rows=$s->fetchAll(PDO::FETCH_ASSOC);foreach($rows as &$r){foreach($r as &$v)if(is_resource($v))$v=stream_get_contents($v);ksort($r);}unset($r);$record=['layer'=>'independent physical PDO oracle','queryString'=>$s->queryString,'execute_params'=>$params,'params_mode'=>'PDOStatement.execute(array), values bind as strings by PDO unless null','rowCount'=>$s->rowCount(),'rows'=>$rows];$json=json_encode($record,JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION);if($json===false){$error=json_last_error_msg();unset($record['rows']);$record['rows_serialized_bytes_base64']=base64_encode(serialize($rows));$record['encoding_failure_preserved']=$error;$json=json_encode($record,JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION);}file_put_contents($runtime.'/oracle.jsonl',$json."\n",FILE_APPEND|LOCK_EX);chmod($runtime.'/oracle.jsonl',0600);return $rows;};
$db=$connect();$check($dm?$db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn()==='AIZHCT_APP':($db->query('SELECT DATABASE()')->fetchColumn()===getenv('POC_AI_SCHEMA')&&strpos($db->query('SELECT VERSION()')->fetchColumn(),'5.6.')===0),'Actual database identity');
$read=static function($sql,$p=[])use($connect,$query){return $query($connect(),$sql,$p);};
$pks=['user'=>'user_id','upload_file'=>'file_id','goods'=>'goods_id','order'=>'order_id','order_goods'=>'order_goods_id','order_address'=>'order_address_id','order_delivery'=>'delivery_id','order_delivery_goods'=>'id','payment_trade'=>'trade_id','express'=>'express_id','order_refund'=>'order_refund_id','order_refund_image'=>'id','order_refund_address'=>'id','goods_sku'=>'id','goods_image'=>'id','goods_category_rel'=>'id','goods_service_rel'=>'id','goods_spec_rel'=>'id','printer'=>'printer_id','recharge_order'=>'order_id','recharge_order_plan'=>'order_plan_id','order_export'=>'id','store_user'=>'store_user_id','store_user_role'=>'id','store_user_relation'=>'id','store_role'=>'role_id','store_role_menu'=>'id','store'=>'store_id','equipment'=>'id','dishes'=>'id','dishes_img'=>'id','store_setting'=>$dm?'"KEY"':'`key`','user_points_log'=>'log_id','user_balance_log'=>'log_id','user_feedback'=>'id','user_grade'=>'grade_id'];
$own=static function()use($read,$pks){$out=[];foreach($pks as $t=>$pk)$out[$t]=$read('SELECT * FROM yoshop_'.$t.' WHERE store_id IN (2147001111,2147001112,2147001113) ORDER BY '.$pk);return $out;};
$small=static function($module)use($read,$tenants){$t=$tenants[$module];$out=[];foreach(['user'=>'user_id','upload_file'=>'file_id','user_points_log'=>'log_id','user_balance_log'=>'log_id','user_feedback'=>'id','user_grade'=>'grade_id'] as $name=>$pk)$out[$name]=$read('SELECT * FROM yoshop_'.$name.' WHERE store_id=? ORDER BY '.$pk,[$t]);return $out;};
function commentApp(string $root,string $runtime):\think\App{
 if(!defined('TP_ENV')){define('TP_ENV','poc');define('BUSINESS','aizhct');define('ENTERPRISE_NO','10001');require $root.'/vendor/autoload.php';spl_autoload_register(static function($class)use($root){if(preg_match('/printer|MQTT|BaiduDishes|\\\\Face$|storage\\\\Driver|QwRobot/i',$class))throw new RuntimeException('Forbidden external service/SDK');foreach(['app\\'=>'app/','cores\\'=>'cores/'] as $p=>$d)if(strpos($class,$p)===0){$f=$root.'/'.$d.str_replace('\\','/',substr($class,strlen($p))).'.php';if(is_file($f))require $f;}},true,true);}
 $app=new \think\App($root);$app->setEnvName('poc');$app->setRuntimePath($runtime.'/runtime/');$app->initialize();$app->config->set(['default'=>'file','stores'=>['file'=>['type'=>'File','path'=>$runtime.'/cache/','prefix'=>'','expire'=>0]]],'cache');$app->instance('cache',new \think\Cache($app));$log=$app->config->get('log');$log['close']=true;foreach($log['channels'] as &$c)$c['close']=true;unset($c);$app->config->set($log,'log');$app->instance('log',new \think\Log($app));$app->log->channel()->close();return $app;
}
function guardedApp(string $root,string $runtime,string $scenario):\think\App{
 $app=commentApp($root,$runtime);require_once __DIR__.'/ReadOnlyPdo.php';ReadSqlGate::$runtime=$runtime;ReadSqlGate::$scenario=$scenario;
 $cfg=$app->config->get('database');$conn=$cfg['connections']['mysql'];$conn['type']=getenv('POC_DIALECT')==='dm'?'\\'.GuardDm::class:'\\'.GuardMysql::class;
 foreach(['HOST'=>'hostname','PORT'=>'hostport','SCHEMA'=>'database','USER'=>'username','PASSWORD'=>'password','CHARSET'=>'charset'] as $k=>$to)$conn[$to]=getenv('POC_AI_'.$k);$conn['prefix']='yoshop_';$conn['debug']=false;$conn['trigger_sql']=true;$conn['break_reconnect']=false;$conn['fields_cache']=false;$conn['dsn']='';$conn['params']=[];$cfg['default']='mysql';$cfg['connections']=['mysql'=>$conn];$app->config->set($cfg,'database');$app->db->setConfig($app->config);return $app;
}
