<?php
require __DIR__.'/common.php';
$approved='fbd43e6c40efec4f71f943d822faeff1fc4fcab5f0b7cb875a706699edfccd12';
if(hash_file('sha256',__DIR__.'/fixture-plan-first4.json')!==$approved||is_file(__DIR__.'/private/fixture-journal.json'))throw new RuntimeException('Unapproved plan or replay');
$before=$source(true);foreach(['staff','dishes','recommend','menu']as $k)if($before[$k]!==[])throw new RuntimeException('Fresh marker collision');
$lease=json_decode(file_get_contents(__DIR__.'/preflight-lease-'.$lane.'.json'),true);
$actor=$before['actor'][0]??[];$prior=$lease['operator'][0]??[];foreach($prior as $k=>$v)if(!array_key_exists($k,$actor)||$actor[$k]!==$v)throw new RuntimeException('Actor lease drift '.$k);
if(count($before['actor'])!==1||(int)$actor['type']!==0||(int)$actor['is_delete']!==0)throw new RuntimeException('Exact CDX actor');
$fresh=[];
foreach(['staff','dishes','menu_recommend','date_menu']as $t){
 $fresh[$t]=$lane==='B'?$q('SELECT COLUMN_NAME,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,EXTRA FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY ORDINAL_POSITION',['ydy_'.$t]):$q('SELECT COLUMN_NAME,DATA_TYPE,DATA_LENGTH,DATA_PRECISION,DATA_SCALE,NULLABLE,DATA_DEFAULT FROM USER_TAB_COLUMNS WHERE TABLE_NAME=? ORDER BY COLUMN_ID',['YDY_'.strtoupper($t)]);
 if($fresh[$t]!==$lease['schema'][$t])throw new RuntimeException('Column/default drift '.$t);
 $triggers=$lane==='B'?$q('SELECT TRIGGER_NAME,ACTION_TIMING,EVENT_MANIPULATION,ACTION_STATEMENT FROM information_schema.TRIGGERS WHERE EVENT_OBJECT_SCHEMA=DATABASE() AND EVENT_OBJECT_TABLE=? ORDER BY TRIGGER_NAME',['ydy_'.$t]):$q('SELECT * FROM USER_TRIGGERS WHERE TABLE_NAME=? ORDER BY TRIGGER_NAME',['YDY_'.strtoupper($t)]);
 $constraints=$lane==='B'?$q('SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY CONSTRAINT_NAME',['ydy_'.$t]):$q('SELECT CONSTRAINT_NAME,CONSTRAINT_TYPE,STATUS,SEARCH_CONDITION FROM USER_CONSTRAINTS WHERE TABLE_NAME=? ORDER BY CONSTRAINT_NAME',['YDY_'.strtoupper($t)]);
 $indexes=$lane==='B'?$q('SELECT INDEX_NAME,NON_UNIQUE,SEQ_IN_INDEX,COLUMN_NAME FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? ORDER BY INDEX_NAME,SEQ_IN_INDEX',['ydy_'.$t]):$q('SELECT INDEX_NAME,UNIQUENESS,INDEX_TYPE FROM USER_INDEXES WHERE TABLE_NAME=? ORDER BY INDEX_NAME',['YDY_'.strtoupper($t)]);
 if($triggers!==[]||$constraints!==$lease['objects'][$t]['constraints']||$indexes!==$lease['objects'][$t]['indexes'])throw new RuntimeException('Object drift '.$t);
}
foreach(json_decode(file_get_contents(__DIR__.'/source-lock.json'),true)as $file=>$sha)if(hash_file('sha256',__DIR__.'/source/application/'.$file)!==$sha)throw new RuntimeException('Source drift');
$save('fixture-before.json',$before);$save('fixture-fresh-metadata.json',$fresh);
$j=['lane'=>$lane,'approved_plan_sha256'=>$approved,'committed'=>false,'events'=>[]];$save('fixture-journal.json',$j);
$db->beginTransaction();try{foreach($plan['rows']as $row){
 $entry=['queryString'=>$row['sql'],'binds'=>$row['pdo_binds'],'sent'=>true,'success'=>false];$j['events'][]=$entry;$i=count($j['events'])-1;$save('fixture-journal.json',$j);
 $s=$db->prepare($row['sql']);foreach($row['pdo_binds']as $k=>$v)$s->bindValue($k+1,$v['value'],$v['type']);$s->execute();$j['events'][$i]['success']=true;$j['events'][$i]['rowCount']=$s->rowCount();$j['events'][$i]['errorInfo']=$s->errorInfo();$save('fixture-journal.json',$j);
 if($s->rowCount()!==1)throw new RuntimeException('Exact one row');
 $rows=$q('SELECT * FROM '.$row['table'].' WHERE uuid=?',[$row['values']['uuid']]);if(count($rows)!==1)throw new RuntimeException('Exact readback');
 foreach($row['values']as $k=>$v){$got=$rows[0][$k];$ok=is_numeric($v)?is_numeric($got)&&(float)$got===(float)$v:$got===$v;if($k==='create_time')$ok=$got===$v||$got===$v.'.000000';if(!$ok)throw new RuntimeException('Readback '.$row['table'].'.'.$k);}
 $j['events'][$i]['original_row']=$rows[0];$save('fixture-journal.json',$j);
}$db->commit();$j['committed']=true;$save('fixture-journal.json',$j);}catch(Throwable $e){if($db->inTransaction())$db->rollBack();$j['error']=['class'=>get_class($e),'message'=>$e->getMessage()];$save('fixture-journal.json',$j);throw $e;}
$after=$source(true);$save('batch-before.json',$after);$save('fixture-oracle.json',$GLOBALS['NR_ORACLE']);
echo json_encode(['lane'=>$lane,'INSERT'=>6,'UPDATE'=>0,'DELETE'=>0,'DDL'=>0,'committed'=>true]),"\n";
