<?php

declare(strict_types=1);

namespace Tests\Support;

use PHPUnit\Framework\Assert;

final class ProtectedSnapshotAssertions
{
    /**
     * @param  array<string, mixed>  $payload
     */
    public static function assertRedactedPath(array $payload, string $jsonPointer): void
    {
        Assert::assertSame('[REDACTED]', self::valueAtPointer($payload, $jsonPointer));
    }

    /**
     * @param  array<string, mixed>  $secretFingerprints
     */
    public static function assertFingerprint(array $secretFingerprints, string $bucket, string $jsonPointer): void
    {
        $bucketFingerprints = $secretFingerprints[$bucket] ?? null;

        Assert::assertIsArray($bucketFingerprints);
        Assert::assertArrayHasKey($jsonPointer, $bucketFingerprints);
        Assert::assertMatchesRegularExpression('/^[a-f0-9]{64}$/', (string) $bucketFingerprints[$jsonPointer]);
    }

    /**
     * @param  array<string, mixed>  $payload
     */
    private static function valueAtPointer(array $payload, string $jsonPointer): mixed
    {
        $segments = explode('/', ltrim($jsonPointer, '/'));
        $value = $payload;

        foreach ($segments as $segment) {
            $segment = str_replace(['~1', '~0'], ['/', '~'], $segment);

            if (! is_array($value) || ! array_key_exists($segment, $value)) {
                return null;
            }

            $value = $value[$segment];
        }

        return $value;
    }
}
