<?php
declare(strict_types=1);
$lane=$argv[1]??'';$action=$argv[2]??'';if(!in_array($lane,['B','C'],true)||!in_array($action,['metadata','start','run','recover','cli','export','cleanup','identity','stop'],true))exit(78);
$env=getenv();$port=$lane==='B'?18421:18422;
if($lane==='B'){$ini=parse_ini_file('/workspace/zhct/zhctproject/ai_api/.env.local',true,INI_SCANNER_RAW);foreach(['DATABASE'=>'POC_AI_','DATABASE_ZHCT'=>'POC_'] as $section=>$prefix)foreach(['HOSTNAME'=>'HOST','HOSTPORT'=>'PORT','DATABASE'=>'SCHEMA','USERNAME'=>'USER','PASSWORD'=>'PASSWORD'] as $from=>$to){if(!isset($ini[$section][$from]))throw new RuntimeException('Local config incomplete');$env[$prefix.$to]=$ini[$section][$from];}$env['POC_DIALECT']='mysql';$php=['/usr/local/php7.4/bin/php'];$old='/tmp/zhct-http-ai-mysql.j2nxVv';}
else{$cmd=file_get_contents('/proc/53772/cmdline');if(strpos($cmd,'127.0.0.1:18102')===false)throw new RuntimeException('Parent identity drift');$env=[];foreach(explode("\0",file_get_contents('/proc/53772/environ')) as $entry){$p=explode('=',$entry,2);if(count($p)===2)$env[$p[0]]=$p[1];}if(($env['POC_AI_HOST']??'')!=='127.0.0.1'||($env['POC_AI_PORT']??'')!=='5238'||($env['POC_AI_SCHEMA']??'')!=='AIZHCT_APP')throw new RuntimeException('DM target drift');$php=['/www/server/php/74/bin/php','-c','/www/server/php/74/etc/php-cli.ini','-d','extension=/home/dmdba/dmdbms/drivers/php_pdo/libphp74_dm.so','-d','extension=/home/dmdba/dmdbms/drivers/php_pdo/php74_pdo_dm.so'];$old='/tmp/zhct-ai-http-20260929.3XDj3w';}
$env['PAGE_LANE']=$lane;$env['PAGE_BASE']='http://127.0.0.1:'.$port;$env['POC_EXTERNAL_STUBS']='1';$env['POC_REAL_QUEUE']='0';$env['PAGE_ROOT']=__DIR__.'/source';$env['POC_TARGET_ROOT']=$env['PAGE_ROOT'];$env['PAGE_RUNTIME']=__DIR__.'/private';
if($action==='start'){if($s=@fsockopen('127.0.0.1',$port,$e,$m,1)){fclose($s);throw new RuntimeException('Port occupied');}foreach(['vendor','config','route'] as $n)if(!file_exists(__DIR__.'/source/'.$n))symlink($old.'/'.$n,__DIR__.'/source/'.$n);foreach(['public','runtime'] as $n)if(!is_dir(__DIR__.'/source/'.$n))mkdir(__DIR__.'/source/'.$n,0700);if(!is_dir(__DIR__.'/private'))mkdir(__DIR__.'/private',0700);$args=array_merge($php,['-d','display_errors=0','-d','log_errors=0','-S','127.0.0.1:'.$port,'-t',__DIR__,__DIR__.'/router.php']);$cmd='nohup '.implode(' ',array_map('escapeshellarg',$args)).' </dev/null >/dev/null 2>&1 & echo $!';$p=proc_open($cmd,[1=>['pipe','w'],2=>['pipe','w']],$pipes,null,$env);$pid=trim(stream_get_contents($pipes[1]));$err=stream_get_contents($pipes[2]);fclose($pipes[1]);fclose($pipes[2]);if(proc_close($p)!==0||!ctype_digit($pid)||$err!=='')throw new RuntimeException('Start failed');file_put_contents(__DIR__.'/private/state.json',json_encode(['pid'=>(int)$pid,'port'=>$port]));chmod(__DIR__.'/private/state.json',0600);echo json_encode(['lane'=>$lane,'pid'=>(int)$pid,'port'=>$port]),"\n";exit;}
if($action==='stop'){$s=json_decode(file_get_contents(__DIR__.'/private/state.json'),true);$cmd=str_replace("\0",' ',file_get_contents('/proc/'.$s['pid'].'/cmdline'));if(strpos($cmd,__DIR__.'/router.php')===false||strpos($cmd,':'.$port)===false)throw new RuntimeException('Stop drift');posix_kill($s['pid'],SIGTERM);$closed=false;for($i=0;$i<20;$i++){usleep(100000);$socket=@fsockopen('127.0.0.1',$port,$e,$m,1);if(!$socket){$closed=true;break;}fclose($socket);}if(!$closed)throw new RuntimeException('Stopped worker port still open');$f=__DIR__.'/resource-cleanup-'.$lane.'.json';if(is_file($f)){$r=json_decode(file_get_contents($f),true);$r['worker_shutdown']='exact PID/router/port verified stopped';$r['final_worker_pid']=$s['pid'];$r['port']=$port;$r['port_closed']=true;file_put_contents($f,json_encode($r,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES));}echo '{"stopped":true,"port_closed":true}',"\n";exit;}
$env['PAGE_RESUME']=$action==='recover'?'1':'0';$map=['metadata'=>'read_metadata','run'=>'run','recover'=>'run','cli'=>'final_read','export'=>'export','cleanup'=>'cleanup','identity'=>'identity'];$p=proc_open(array_merge($php,[__DIR__.'/'.$map[$action].'.php']),[0=>STDIN,1=>STDOUT,2=>STDERR],$pipes,null,$env);exit(proc_close($p));
