<?php

declare (strict_types=1);
namespace GuardDog\Vendor\Webauthn\CeremonyStep;

use GuardDog\Vendor\Webauthn\AttestationStatement\AttestationStatementSupportManager;
use GuardDog\Vendor\Webauthn\AuthenticatorAssertionResponse;
use GuardDog\Vendor\Webauthn\AuthenticatorAttestationResponse;
use GuardDog\Vendor\Webauthn\Exception\AuthenticatorResponseVerificationException;
use GuardDog\Vendor\Webauthn\PublicKeyCredentialCreationOptions;
use GuardDog\Vendor\Webauthn\PublicKeyCredentialRequestOptions;
use GuardDog\Vendor\Webauthn\PublicKeyCredentialSource;
final class CheckAttestationFormatIsKnownAndValid implements CeremonyStep
{
    public function __construct(private readonly AttestationStatementSupportManager $attestationStatementSupportManager)
    {
    }
    public function process(PublicKeyCredentialSource $publicKeyCredentialSource, AuthenticatorAssertionResponse|AuthenticatorAttestationResponse $authenticatorResponse, PublicKeyCredentialRequestOptions|PublicKeyCredentialCreationOptions $publicKeyCredentialOptions, ?string $userHandle, string $host): void
    {
        $attestationObject = $authenticatorResponse->attestationObject;
        if ($attestationObject === null) {
            return;
        }
        $fmt = $attestationObject->attStmt->fmt;
        $this->attestationStatementSupportManager->has($fmt) || throw AuthenticatorResponseVerificationException::create('Unsupported attestation statement format.');
        $attestationStatementSupport = $this->attestationStatementSupportManager->get($fmt);
        $clientDataJSONHash = hash('sha256', $authenticatorResponse->clientDataJSON->rawData, \true);
        $attestationStatementSupport->isValid($clientDataJSONHash, $attestationObject->attStmt, $attestationObject->authData) || throw AuthenticatorResponseVerificationException::create('Invalid attestation statement.');
    }
}
