<?php
declare(strict_types=1);
function n6DiningExpected(array $proof,$actual):array{
    $expected=unserialize(serialize($proof['body']));$cert=[];
    if(!is_object($actual)||!isset($actual->data)||!is_object($actual->data)||!isset($actual->data->rows)||!is_array($actual->data->rows)||count($actual->data->rows)!==count($expected->data->rows)){throw new RuntimeException('Dining DTO shape mismatch');}
    foreach($expected->data->rows as $i=>$want){$row=$actual->data->rows[$i];if(!is_object($row)||!isset($row->uuid)||$row->uuid!==$want->uuid){throw new RuntimeException('Dining staff row/order mismatch');}$source=$proof['source_sets']['menus'][$row->uuid];
        if(is_array($want->meal_times)&&$want->meal_times===[]){continue;}
        if(!is_object($row->meal_times)||!is_object($want->meal_times)||array_keys(get_object_vars($row->meal_times))!==array_keys(get_object_vars($want->meal_times))){throw new RuntimeException('Dining meal-key JSON shape changed');}
        foreach(get_object_vars($row->meal_times) as $meal=>$value){if(!is_string($value)||!preg_match('/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/D',$value,$match)||!checkdate((int)$match[2],(int)$match[3],(int)$match[1])||(int)$match[1]<1000||(int)$match[4]>23||(int)$match[5]>59||(int)$match[6]>59){throw new RuntimeException('MySQL TIMESTAMP(0) wire format failed');}$matching=[];foreach($source as $entry){if((string)$entry['meal_times']===(string)$meal&&$entry['menu_date']===$row->menu_date&&$entry['create_time']===$value){$matching[]=$entry['id'];}}if(!$matching){throw new RuntimeException('Returned timestamp is not a real SQL group member');}
            // SQL intentionally leaves this representative unspecified; no MAX is assumed.
            $want->meal_times->{$meal}=$value;$want->meal_msg->{$meal}=substr($value,11,5);$cert[]=['meal'=>(string)$meal,'matching_source_pks'=>$matching,'timestamp0_contract'=>true];
        }
    }
    return ['expected'=>$expected,'certificate'=>$cert,'representative_selection_unresolved'=>true];
}
