<?php
declare(strict_types=1);
set_exception_handler(static function(Throwable $e):void{$r=['class'=>get_class($e),'message'=>$e->getMessage(),'trace'=>$e->getTraceAsString()];if(!is_dir(__DIR__.'/private'))mkdir(__DIR__.'/private',0700);$f=__DIR__.'/private/tool-failure-'.str_replace('.','-',uniqid('',true)).'.json';file_put_contents($f,json_encode($r,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT));chmod($f,0600);echo json_encode(['tool_error_class'=>get_class($e),'reason_sha256'=>hash('sha256',$e->getMessage())]),"\n";exit(2);});
$lane=getenv('NR_LANE');$root=getenv('NR_ROOT');if(!in_array($lane,['B','C'],true))throw new RuntimeException('Lane');
defined('TP_ENV')||define('TP_ENV','local');defined('BUSINESS')||define('BUSINESS','');
defined('APP_PATH')||define('APP_PATH',__DIR__.'/source/application/');defined('ROOT_PATH')||define('ROOT_PATH',$root.'/');
$cfg=(static function($f){return require $f;})($lane==='B'?'/workspace/zhct/zhctproject/store/application/database.php':$root.'/application/database.php');
if($lane==='B'){$local=(static function($f){return require $f;})('/workspace/zhct/zhctproject/store/application/config/local/database.php');foreach(['hostname','database','username','password']as $k)if($cfg[$k]!==$local[$k])throw new RuntimeException('Not code-local');if($cfg['charset']!=='utf8'||(string)($cfg['hostport']?:3306)!=='3306'||!empty($cfg['params']))throw new RuntimeException('Effective config drift');}
elseif($cfg['hostname']!=='127.0.0.1'||(string)$cfg['hostport']!=='5237'||$cfg['database']!=='ZHCT_APP')throw new RuntimeException('DM scope');
$dsn=$lane==='B'?'mysql:host='.$cfg['hostname'].';port=3306;dbname='.$cfg['database'].';charset=utf8':'dm:host=127.0.0.1;port=5237;schema=ZHCT_APP';
$options=[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_CASE=>PDO::CASE_LOWER,PDO::ATTR_ORACLE_NULLS=>PDO::NULL_NATURAL,PDO::ATTR_STRINGIFY_FETCHES=>false,PDO::ATTR_EMULATE_PREPARES=>false];
$db=new PDO($dsn,$cfg['username'],$cfg['password'],$options);
$q=static function(string $sql,array $binds=[])use($db):array{
 if(!preg_match('/^SELECT\\b/',$sql)||preg_match('/\\b(INTO|UPDATE|CALL|SLEEP|BENCHMARK)\\b/i',$sql)||strpos($sql,';')!==false)throw new RuntimeException('Oracle SELECT gate');
 $e=['queryString'=>$sql,'binds'=>$binds,'script'=>basename($_SERVER['SCRIPT_FILENAME']??''),'prepared'=>false,'execute_success'=>false];$rows=[];
 $persist=static function($event){$dir=__DIR__.'/private';if(!is_dir($dir))mkdir($dir,0700);$f=$dir.'/oracle-read-receipts.json';$all=is_file($f)?json_decode(file_get_contents($f),true):[];$all[]=$event;file_put_contents($f,json_encode($all,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_PRESERVE_ZERO_FRACTION));chmod($f,0600);};
 try{$s=$db->prepare($sql);$e['prepared']=true;$typed=[];foreach($binds as $i=>$v){$type=is_int($v)?1:($v===null?0:2);$s->bindValue($i+1,$v,$type);$typed[]=['value'=>$v,'PDO_type'=>$type,'php_type'=>gettype($v)];}$e['typed_binds']=$typed;$s->execute();$e['execute_success']=true;
 while($row=$s->fetch(PDO::FETCH_ASSOC)){foreach($row as &$v)if(is_resource($v))$v=stream_get_contents($v);unset($v);$rows[]=array_change_key_case($row,CASE_LOWER);if(count($rows)>500)throw new RuntimeException('Oracle row cap');}
 $e['rows']=preg_match('/FROM ydy_config /',$sql)?null:$rows;$e['rows_count']=count($rows);$e['rows_sha256']=preg_match('/FROM ydy_config /',$sql)?hash('sha256',json_encode($rows,JSON_PRESERVE_ZERO_FRACTION)):null;$e['rowCount']=$s->rowCount();$e['errorInfo']=$s->errorInfo();$GLOBALS['NR_ORACLE'][]=$e;$persist($e);return $rows;
 }catch(Throwable $x){$e['error']=['class'=>get_class($x),'message'=>$x->getMessage()];$persist($e);throw $x;}
};
$save=static function($name,$v){if(!is_dir(__DIR__.'/private'))mkdir(__DIR__.'/private',0700);chmod(__DIR__.'/private',0700);$j=json_encode($v,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|JSON_PRESERVE_ZERO_FRACTION);if($j===false)throw new RuntimeException('Invalid UTF8 not normalized');file_put_contents(__DIR__.'/private/'.$name,$j);chmod(__DIR__.'/private/'.$name,0600);};
$marker='CDXNF11F5';$productUuid=$lane==='B'?'B8247519-0EDA-6239-9A8A-FEA2D6C86F4B':'FCEECEFB-C32E-4977-8A65-EE2210A42095';$templateUuid=$lane==='B'?'50C7341D-2314-E40F-07F6-484816A886BB':'EE5C28D0-A06E-F9B4-2EA6-AB2E866C091F';
$source=static function()use($q,$lane,$marker){$r=[];foreach(['nutrition','nutrition_template','nutrition_set','nutrition_category','nutrition_time']as $t)$r[$t]=$q('SELECT * FROM ydy_'.$t.' WHERE name LIKE ? ORDER BY id',[$marker.'%']);$templates=array_column($r['nutrition_template'],'uuid');$r['nutrition_template_ext']=$q('SELECT * FROM ydy_nutrition_template_ext WHERE template_uuid IN (?,?) ORDER BY id',$templates);$r['actor']=$q('SELECT id,uuid,account,name,type,status,is_delete,user_type,staff_uuid FROM ydy_user WHERE id=? AND account LIKE ?',[$lane==='B'?97260:2791,'CDX%']);$clock=$q('SELECT id,config_key,config_value,status FROM ydy_config WHERE config_key IN (?,?,?,?,?,?) ORDER BY id',['morning_start','morning_end','noon_start','noon_end','night_start','night_end']);$r['config_hash']=['count'=>count($clock),'sha256'=>hash('sha256',json_encode($clock,JSON_PRESERVE_ZERO_FRACTION))];foreach(['nutrition','nutrition_template']as $t){$r[$t.'_native']=[];foreach($r[$t]as $row){$fields=['power','carbohydrate','protein','fat','sodium'];if($t==='nutrition')$fields[]='use_weight';$expr=[];foreach($fields as $f){$expr[]=$f;$expr[]=$lane==='B'?$f.'+0e0 AS '.$f.'_computed':'CAST('.$f.' AS DOUBLE) AS '.$f.'_computed';}$n=$q('SELECT '.implode(',',$expr).' FROM ydy_'.$t.' WHERE uuid=?',[$row['uuid']]);$bits=[];foreach($n[0]??[]as $f=>$v)$bits[$f]=['type'=>gettype($v),'bits64'=>is_float($v)?bin2hex(pack('d',$v)):null,'value'=>$v];$r[$t.'_native'][]=['uuid'=>$row['uuid'],'fields'=>$bits];}}return $r;};
