<?php

declare(strict_types=1);

namespace NoahVet\Reef\Security\IAM;

use Firebase\JWT\JWK;
use Firebase\JWT\Key;
use NoahVet\Reef\Exception\OAuthRequestException;
use NoahVet\Reef\Factory\HttpClientFactoryInterface;

class IAMPublicKeyProvider implements IAMPublicKeyProviderInterface
{
    /**
     * @var array<string, Key>|null
     */
    private ?array $iamKeys = null;

    public function __construct(
        private readonly string $reefOAuthBaseUrl,
        private readonly HttpClientFactoryInterface $httpClientFactory,
    ) {
    }

    /**
     * @return array<string, Key>
     */
    public function getIAMPublicKeys(): array
    {
        if (null === $this->iamKeys) {
            $client = $this->httpClientFactory->create();

            $openIdKeysResponse = $client->sendRequest(
                $this->httpClientFactory->getRequestFactory()->createRequest(
                    'GET',
                    $this->reefOAuthBaseUrl.'/openid/jwt-keys.json',
                ),
            );

            if (200 !== $openIdKeysResponse->getStatusCode()) {
                throw new OAuthRequestException("Can't load IAM's public keys");
            }

            $keyDetails = \json_decode($openIdKeysResponse->getBody()->getContents(), true);

            if (!\is_array($keyDetails) || !\is_array($keyDetails['keys'] ?? null)) {
                throw new OAuthRequestException('IAM payload is invalid');
            }

            $this->iamKeys = JWK::parseKeySet($keyDetails);
        }

        return $this->iamKeys;
    }
}
