<?php

namespace Drupal\miniorange_webauthn\MoDto;

use ParagonIE\ConstantTime\Base64UrlSafe;
use Symfony\Component\Uid\Uuid;
use Webauthn\AttestedCredentialData;
use Webauthn\AuthenticatorAssertionResponse;
use Webauthn\AuthenticatorData;
use Webauthn\AuthenticatorResponse;
use Webauthn\CollectedClientData;
use Webauthn\Exception\InvalidDataException;
use Webauthn\PublicKeyCredential;

class MoPubKeyCredAssertionRespDto extends PublicKeyCredential
{
  /**
   * @throws InvalidDataException
   * @throws \JsonException
   */
  public static function build(string $id, string $type, string $rawId, array $response)
  {
    $response = AuthenticatorAssertionResponse::create(
      CollectedClientData::createFormJson($response['clientDataJSON']),
      AuthenticatorData::create(...self::parseAuthData($response['authenticatorData'])),
      $response['signature'],
      $response['userHandle']
    );
    return parent::create($type, $rawId, $response);
  }

  public static function parseAuthData(string $authData): array {
    $binary = Base64UrlSafe::decode($authData);

    $rpIdHash = substr($binary, 0, 32);
    $flags = substr($binary, 32, 1);
    $signCountBin = substr($binary, 33, 4);
    $signCount = unpack('N', $signCountBin)[1]; // big-endian unsigned int

    // Assertions don't usually include attestedCredentialData or extensions
    $attestedCredentialData = null;
    $extensions = null;

    return [
      'authData' => $authData,
      'rpIdHash' => bin2hex($rpIdHash),
      'flags' => $flags,
      'signCount' => $signCount,
      'attestedCredentialData' => $attestedCredentialData,
    ];
  }
}
