<?php

declare(strict_types=1);

/** Full recursive JSON key/type contract, excluding only dynamic trace_id. */
function giftLogJsonShape(string $rawBody): array
{
    $object = json_decode($rawBody);
    if (!is_object($object)) {
        throw new RuntimeException('Gift JSON contract source invalid');
    }
    unset($object->trace_id);
    $visit = null;
    $visit = static function ($value) use (&$visit) {
        if (is_object($value)) {
            $fields = get_object_vars($value);
            ksort($fields, SORT_STRING);
            $result = [];
            foreach ($fields as $name => $item) {
                $result[$name] = $visit($item);
            }
            return ['object' => $result];
        }
        if (is_array($value)) {
            $result = [];
            foreach ($value as $item) $result[] = $visit($item);
            return ['array' => $result];
        }
        return gettype($value);
    };
    return $visit($object);
}
