<?php

namespace Velis\RateLimiter;

/**
 * @author Szymon Janaczek <szymon.janaczek@velistech.com>
 */
interface LeakyBucketRateLimiterInterface
{
    /**
     * Set an identifier for the rate limiter instance.
     */
    public function setIdentifier(string $identifier): self;

    /**
     * Attempt to perform an action under the rate limit.
     *
     * @param string $key A unique key to identify the action being rate limited.
     * @param int $rateLimit The maximum number of allowed attempts in a given time period.
     * @param float $leakRate The rate at which the bucket leaks, reducing the number of attempts over time.
     * @param int $decaySeconds The time window (in seconds) for which the rate limit is enforced.
     * @throws TooManyAttemptsException
     */
    public function attempt(string $key, int $rateLimit, float $leakRate = 1, int $decaySeconds = 60): void;

    /**
     * Attempt to perform an action under the rate limit using the identifier.
     *
     * @param int $rateLimit The maximum number of allowed attempts in a given time period.
     * @param float $leakRate The rate at which the bucket leaks, reducing the number of attempts over time.
     * @param string $key A unique key to identify the action being rate limited.
     * @param int $decaySeconds The time window (in seconds) for which the rate limit is enforced.
     * @throws TooManyAttemptsException
     */
    public function attemptByIdentifier(
        int $rateLimit,
        float $leakRate = 1,
        string $key = '',
        int $decaySeconds = 60,
    ): void;

    /**
     * Check if the number of attempts has exceeded the rate limit.
     *
     * @param string $key A unique key to identify the action being rate limited.
     * @param int $rateLimit The maximum number of allowed attempts in a given time period.
     * @param float $leakRate The rate at which the bucket leaks, reducing the number of attempts over time.
     * @return bool True if the rate limit has been exceeded, otherwise false.
     */
    public function isRateLimitExceeded(string $key, int $rateLimit, float $leakRate = 1): bool;

    /**
     * Register a hit (increment the attempt count) for a given key.
     *
     * @param string $key A unique key to identify the action being rate limited.
     * @param float $leakRate The rate at which the bucket leaks, reducing the number of attempts over time.
     * @param int $decaySeconds The time window (in seconds) for which the rate limit is enforced.
     */
    public function hit(string $key, float $leakRate = 1, int $decaySeconds = 60): void;

    /**
     * Get the number of attempts for a given key.
     *
     * @param string $key A unique key to identify the action being rate limited.
     * @return int The number of attempts made.
     */
    public function attempts(string $key): int;
}
