<?php
require __DIR__.'/common.php';$phase=$argv[1]??'';if(!in_array($phase,['original','candidate'],true))throw new RuntimeException('Phase');if($phase==='candidate'&&!is_file(__DIR__.'/private/root-candidate-approved.json'))throw new RuntimeException('Root main SHA first');
$attemptFile='attempts-'.$phase.'.json';if(is_file(__DIR__.'/private/'.$attemptFile))throw new RuntimeException('Successful writes never replay');$auth=json_decode(file_get_contents(__DIR__.'/private/auth.json'),true);$port=$lane==='B'?18921:18922;$attempts=[];$save($attemptFile,$attempts);$own=[];
$send=static function($case)use(&$attempts,$attemptFile,$save,$auth,$port,$phase){$save('current-case.json',$case);$payload=$case['encoding']==='json'?json_encode($case['params'],JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION):http_build_query($case['params']);$attempts[]=['case'=>$case,'payload_base64'=>base64_encode($payload),'started'=>true,'complete'=>false];$i=count($attempts)-1;$save($attemptFile,$attempts);$ctx=stream_context_create(['http'=>['method'=>'POST','header'=>'Content-Type: '.($case['encoding']==='json'?'application/json':'application/x-www-form-urlencoded')."\r\nToken: ".$auth['token']."\r\nX-CDX-Case: ".$case['label']."\r\n",'content'=>$payload,'ignore_errors'=>true,'follow_location'=>0,'timeout'=>30]]);$body=file_get_contents('http://127.0.0.1:'.$port.$case['path'],false,$ctx);$attempts[$i]['complete']=$body!==false;$attempts[$i]['headers']=$http_response_header??[];$attempts[$i]['body_base64']=$body===false?null:base64_encode($body);$save($attemptFile,$attempts);$wire=__DIR__.'/private/wire-'.$phase.'-'.$case['label'].'.json';if($body===false||!is_file($wire))throw new RuntimeException('HTTP missing evidence; stop without replay');return json_decode(file_get_contents($wire),true);};
foreach($plan['cases']as $spec){$template=strpos($spec['label'],'template-')===0;$params=$template?['name'=>$marker.'-'.$phase.'-template','train_status'=>1,'demo'=>$marker.'-'.$spec['label']]:$plan['base_product'];$params['name']=str_replace('{phase}',$phase,$params['name']);
 if(!$template){if(isset($spec['scope'])&&strpos($spec['scope'],'setB')===0)$params['set_uuid']=$plan['preparation']['rows'][2]['row']['uuid'];if(isset($spec['scope'])&&strpos($spec['scope'],'catB')!==false)$params['nutrition_category_uuid']=$plan['preparation']['rows'][4]['row']['uuid'];}
 if(!in_array($spec['label'],['p-add','template-add'],true)){$key=$template?'template_uuid':'product_uuid';if(empty($own[$key]))throw new RuntimeException('Prior own generated row missing');$params['uuid']=$own[$key];}
 $vector=is_array($spec['vector'])?$spec['vector']:$plan[$spec['vector'].'_vector'];$params=array_merge($params,$vector);
 if($template){$ext=$plan['template_ext'];$ext['nutrition_uuid']=$own['product_uuid'];if(isset($spec['ext_override']))$ext=array_merge($ext,$spec['ext_override']);$params['template_ext']=[$ext];}
 $case=['phase'=>$phase,'label'=>$spec['label'],'path'=>$spec['path'],'encoding'=>$spec['encoding'],'params'=>$params,'own'=>$own];$wire=$send($case);
 foreach(['nutrition'=>'product_uuid','nutrition_template'=>'template_uuid']as $t=>$key){foreach($wire['after'][$t]??[]as $row)if($row['name']===$marker.'-'.$phase.'-'.($t==='nutrition'?'product':'template'))$own[$key]=$row['uuid'];}
 $key=$template?'template_uuid':'product_uuid';if(empty($own[$key]))throw new RuntimeException('No actual own row for info');
 $send(['phase'=>$phase,'label'=>$spec['label'].'-info','path'=>$spec['info'],'encoding'=>'json','params'=>['uuid'=>$own[$key]],'own'=>$own]);
 foreach($wire['native']as $event)if(isset($event['error'])&&($event['error']['class']??'')==='RuntimeException')throw new RuntimeException('Native scope gate red; preserve no replay');
}
$save('phase-'.$phase.'-final.json',['source'=>$source(),'oracle'=>$GLOBALS['NF_ORACLE'],'own'=>$own]);echo json_encode(['lane'=>$lane,'phase'=>$phase,'HTTP'=>count($attempts),'completed'=>true]),"\n";
