<?php
declare(strict_types=1);require __DIR__.'/native.php';
ck(!file_exists($runtime.'/prepared.json')&&!file_exists($runtime.'/prepare-attempt.json'),'Never repeat preparation');
saveOnce('prepare-attempt.json',['lane'=>$lane,'started_at'=>date('c'),'authorization_plan_sha256'=>'50a7b2dba60b68b81aa6685676fdfb821da9441207d47108541e7a722321262a']);$proof=sourceProof();$old=oldProtection();$base=json_decode(file_get_contents($runtime.'/protection-'.$lane.'.json'),true)['protected'];foreach($old as $key=>$rows){if($key==='ZHCT.exact_config_hashes')ck($rows===$base[$key]['sha256'],'Old config fullrow hash');else ck($rows===$base[$key]['rows'],'Old fullrow protection '.$key);}
$planRaw=file_get_contents(__DIR__.'/typed-prepare-plan.json');ck(hash('sha256',$planRaw)==='50a7b2dba60b68b81aa6685676fdfb821da9441207d47108541e7a722321262a','Exact typed7 plan');$plan=json_decode($planRaw,true);$validation=json_decode(file_get_contents($runtime.'/prepare-validation-'.$lane.'.json'),true);ck($validation['errors']===[],'Fresh schema/collision validation');foreach($validation['native_events'] as $e)ck((int)$e['rows'][0]['n']===0,'Collision zero');
// Repeat only the exact already approved read checks immediately before any INSERT.
foreach($validation['native_events'] as $e){$params=array_column($e['bindValue'],'value');$rows=readNative($e['connection'],$e['queryString'],$params);ck((int)$rows[0]['n']===0,'Immediate marker collision zero');}
$ids=[];$rows=[];$writes=[];$active=[];
try{foreach(['AI','ZHCT'] as $db){$p=nativePdo($db);ck($p->beginTransaction(),'Prepare native begin');$active[$db]=true;event('prepare-native.jsonl',['connection'=>$db,'operation'=>'beginTransaction','success'=>true]);foreach($plan['rows'] as $entry){if(($entry['connection']==='mysql'?'AI':'ZHCT')!==$db)continue;$values=[];$bind=[];foreach($entry['values'] as $key=>[$type,$v]){if($type==='ref'){ck(isset($ids[$v]),'Prior generated identity');$v=$ids[$v];}$values[$key]=$v;$bind[]=['column'=>$key,'value'=>$v,'pdo_type'=>$type==='str'?PDO::PARAM_STR:PDO::PARAM_INT,'php_type'=>gettype($v)];}ck(!isset($values[$entry['pk']]),'Never supply identity');$sql='INSERT INTO '.$entry['table'].' ('.implode(',',array_keys($values)).') VALUES ('.implode(',',array_fill(0,count($values),'?')).')';$s=$p->prepare($sql);foreach($bind as $i=>$b)ck($s->bindValue($i+1,$b['value'],$b['pdo_type']),'Actual prepare binding');$ok=$s->execute();$rec=['connection'=>$db,'name'=>$entry['name'],'queryString'=>$s->queryString,'bindValue'=>$bind,'execute'=>$ok,'rowCount'=>$s->rowCount()];event('prepare-native.jsonl',$rec);ck($ok&&$rec['rowCount']===1,'Single prepare INSERT affected1');$id=$p->lastInsertId();event('prepare-native.jsonl',['connection'=>$db,'name'=>$entry['name'],'operation'=>'lastInsertId','value'=>$id,'php_type'=>gettype($id)]);ck(ctype_digit((string)$id)&&(int)$id>0,'Real generated identity');$ids[$entry['name']]=(int)$id;$actual=readNative($db,'SELECT * FROM '.$entry['table'].' WHERE '.$entry['pk'].'=?',[$id]);ck(count($actual)===1,'Real identity fullrow readback');foreach($values as $key=>$v)ck((string)$actual[0][$key]===(string)$v,'Typed plan stored field '.$entry['name'].'.'.$key);$rows[$entry['name']]=$actual[0];$writes[]=$rec;}ck($p->commit(),'Prepare native commit');$active[$db]=false;event('prepare-native.jsonl',['connection'=>$db,'operation'=>'commit','success'=>true]);}ck(count($writes)===7,'Exactly7 preparation');$after=oldProtection();ck($old===$after,'Old fullrow preserved after preparation');saveOnce('prepared.json',['lane'=>$lane,'ids'=>$ids,'rows'=>$rows,'writes'=>$writes,'source'=>$proof,'old_protection_before'=>$old,'old_protection_after'=>$after,'finished_at'=>date('c'),'INSERT'=>7,'UPDATE'=>0,'DELETE'=>0,'DDL'=>0,'HTTP'=>0]);echo json_encode(['lane'=>$lane,'prepared7'=>true,'ids'=>$ids,'old_protection_equal'=>true]),"\n";}catch(Throwable $e){foreach($active as $db=>$on)if($on){nativePdo($db)->rollBack();event('prepare-native.jsonl',['connection'=>$db,'operation'=>'rollBack','success'=>true]);}saveOnce('prepare-failed.json',['class'=>get_class($e),'message'=>$e->getMessage(),'ids'=>$ids,'completed_writes'=>$writes,'at'=>date('c')]);throw $e;}
