<?php
declare(strict_types=1);
require __DIR__.'/contract.php';$lane=getenv('SM7_LANE');$runtime=getenv('SM7_RUNTIME');$fixture=smLoad('fixture-private.json');$pre=smLoad('preflight-private.json');$actor=smLoad('actor-private.json');$port=$lane==='B'?18391:18392;
if(is_file(__DIR__.'/worker_state.json')){throw new RuntimeException('Stop owned worker before resource cleanup');}
$socket=@fsockopen('127.0.0.1',$port,$n,$e,1);if($socket){fclose($socket);throw new RuntimeException('Owned port still listening');}
$db=smPdo();$own=hcOwnRows($db,$fixture['seed'],$fixture['ids']);if(smDigest($own)!==smDigest($fixture['own_rows'])){throw new RuntimeException('Retained fixture differs');}
$consumed=hcConsumedSource($db,$fixture['seed'],$fixture['ids'],$pre,$actor,4);$zero=[];foreach($own as $t=>$row){foreach($row as $f=>$v){if(preg_match('/money|balance|cash|subsidy|gift|price/',$f)&&$v!==null){if(!is_numeric($v)||bccomp((string)$v,'0',8)!==0){throw new RuntimeException('Retained funds not zero');}$zero[]=$t.'.'.$f;}}}
$cache=$runtime.'/cache';$removed=0;if(is_dir($cache)){if(is_link($cache)||realpath($cache)!==realpath($runtime).'/cache'){throw new RuntimeException('Private cache boundary');}$it=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($cache,FilesystemIterator::SKIP_DOTS),RecursiveIteratorIterator::CHILD_FIRST);foreach($it as $f){if($f->isLink()){throw new RuntimeException('Unexpected private cache symlink');}if($f->isFile()){unlink($f->getPathname());$removed++;}elseif($f->isDir()){rmdir($f->getPathname());}}}
$remaining=0;if(is_dir($cache)){foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($cache,FilesystemIterator::SKIP_DOTS)) as $f){if($f->isFile()){$remaining++;}}}
$out=['lane'=>$lane,'port'.$port.'_listening'=>false,'worker_state_exists'=>false,'private_cache_files_removed'=>$removed,'private_cache_files_remaining'=>$remaining,'credential_tokens_persisted'=>false,'business_rows_deleted'=>0,'owned_chain_retained'=>true,'database_dml_ddl'=>0,'new_connection_owned_full_rows_verified'=>true,'consumed_source'=>$consumed,'fund_fields_zero'=>$zero,'retained_ids'=>$fixture['ids']];smSave('resource-cleanup-private.json',$out);echo json_encode(['lane'=>$lane,'port_listening'=>false,'cache_remaining'=>$remaining,'retained_rows'=>count($own),'new_connection_consumed_verified'=>true]),PHP_EOL;
