<?php

declare(strict_types=1);

namespace CpCreation\AltchaBundle\Security;

use CpCreation\AltchaBundle\Model\LocalRateLimitDecision;
use Symfony\Component\RateLimiter\RateLimiterFactoryInterface;

final readonly class LocalRateLimiter
{
    public function __construct(
        private RateLimiterFactoryInterface $challengeFactory,
        private RateLimiterFactoryInterface $submissionFactory,
    ) {
    }

    public function consumeChallenge(string $scope, string $clientIp): LocalRateLimitDecision
    {
        return $this->consume($this->challengeFactory, $scope, $clientIp);
    }

    public function consumeSubmission(string $scope, string $clientIp): LocalRateLimitDecision
    {
        return $this->consume($this->submissionFactory, $scope, $clientIp);
    }

    private function consume(RateLimiterFactoryInterface $factory, string $scope, string $clientIp): LocalRateLimitDecision
    {
        $limit = $factory->create(hash('sha256', $scope."\0".$clientIp))->consume();
        if ($limit->isAccepted()) {
            return new LocalRateLimitDecision(true);
        }

        return new LocalRateLimitDecision(
            false,
            max(1, $limit->getRetryAfter()->getTimestamp() - time()),
        );
    }
}
