<?php
require __DIR__.'/common.php';if($lane!=='B'||is_file(__DIR__.'/private/cas-restore-retry1.json'))throw new RuntimeException('Exact B retry1 only');
$origin=json_decode(file_get_contents(__DIR__.'/private/original100.json'),true);$expect=$origin;$expect['dishes'][0]['raw_flag_weight']='0.00';$before=$source(true);$a=$before;$b=$expect;unset($a['sentinel'],$b['sentinel']);if($a!==$b)throw new RuntimeException('Retry original fullzero drift');
$plan=json_decode(file_get_contents(__DIR__.'/log-http-plan.json'),true);$prior=json_decode(file_get_contents(__DIR__.'/private/logs-before10.json'),true);foreach($plan['cases']as $case){$w=json_decode(file_get_contents(__DIR__.'/private/wire-'.$case['label'].'.json'),true);if($w['logs_before']!==$prior||!$w['old_logs_unchanged'])throw new RuntimeException('Prior log drift');$prior=$w['logs_after'];}$logsNow=$logs();if($logsNow!==$prior||count($logsNow)!==166)throw new RuntimeException('Exact166 before restore');
$triggers=$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_dishes']);if($triggers!==[])throw new RuntimeException('Unknown dishes trigger');
$journal=['phase'=>'restore-retry1','before'=>$before,'events'=>[],'committed'=>false,'triggers'=>$triggers];$run=static function($sql,$binds)use($db,&$journal){$s=$db->prepare($sql);foreach($binds as $i=>$v)$s->bindValue($i+1,$v,PDO::PARAM_STR);$s->execute();$rows=[];if(strpos($sql,'SELECT')===0)while($r=$s->fetch(PDO::FETCH_ASSOC))$rows[]=array_change_key_case($r,CASE_LOWER);$e=['queryString'=>$sql,'binds'=>$binds,'success'=>true,'rowCount'=>$s->rowCount(),'errorInfo'=>$s->errorInfo(),'rows'=>$rows];$journal['events'][]=$e;return $e;};
$db->beginTransaction();try{
 $locked=$run('SELECT * FROM ydy_dishes WHERE uuid=? AND create_by=? FOR UPDATE',['C8EAA110-0002-4000-8000-202610110002','CDXNR11A']);if($locked['rows']!==$before['dishes'])throw new RuntimeException('Locked fullzero drift');
 $e=$run('UPDATE ydy_dishes SET raw_flag_weight=?, update_time=update_time WHERE uuid=? AND create_by=? AND raw_flag_weight=?',['100.00','C8EAA110-0002-4000-8000-202610110002','CDXNR11A','0.00']);if($e['rowCount']!==1)throw new RuntimeException('One CAS affected');
 $after=$source(true);$journal['after']=$after;$want=$before;$want['dishes'][0]['raw_flag_weight']='100.00';$x=$after;$y=$want;unset($x['sentinel'],$y['sentinel']);if($x!==$y||$logs()!==$logsNow)throw new RuntimeException('Only raw_flag_weight may change');
 $delta=[];foreach($before['sentinel']as $k=>$v)if($after['sentinel'][$k]!==$v)$delta[$k]=['before'=>$v,'after'=>$after['sentinel'][$k]];$journal['natural_sentinel_deltas']=$delta;$db->commit();$journal['committed']=true;$journal['logs_unchanged']=true;$save('cas-restore-retry1.json',$journal);$save('restored100.json',$after);echo json_encode(['lane'=>'B','phase'=>'restore-retry1','affected'=>1,'committed'=>true,'other_full_columns_unchanged'=>true,'sentinel_changed'=>array_keys($delta)]),"\n";
}catch(Throwable $e){if($db->inTransaction())$db->rollBack();$journal['failure']=['class'=>get_class($e),'message'=>$e->getMessage()];$after=$source(true);$x=$after;$y=$before;unset($x['sentinel'],$y['sentinel']);$journal['rollback_own_verified']=$x===$y&&$logs()===$logsNow;$save('cas-restore-retry1.json',$journal);throw $e;}
