<?php

declare(strict_types=1);

namespace App\Framework\Http\RateLimiter;

/**
 * Konfiguration für verschiedene Rate Limiting Strategien.
 * Diese Klasse ermöglicht die Definition unterschiedlicher Rate-Limits
 * für verschiedene Teile der Anwendung.
 */
final class RateLimiterConfig
{
    /**
     * @var array<string, array{limit: int, window: int}> Pfad-Muster (Regex) => Limit-Konfiguration
     */
    private array $pathLimits = [];

    /**
     * @param int $defaultLimit Standardmäßige Anzahl an erlaubten Anfragen im Zeitfenster
     * @param int $windowSeconds Länge des Zeitfensters in Sekunden
     */
    public function __construct(
        private readonly int $defaultLimit = 60,
        private readonly int $windowSeconds = 60
    ) {
    }

    /**
     * Fügt ein spezifisches Limit für einen Pfad hinzu.
     *
     * @param string $pathPattern Ein regulärer Ausdruck, der den Pfad beschreibt
     * @param int $limit Anzahl der erlaubten Anfragen
     * @param int|null $window Zeitfenster in Sekunden (optional, nutzt Standard wenn nicht angegeben)
     * @return self
     */
    public function addPathLimit(string $pathPattern, int $limit, ?int $window = null): self
    {
        $this->pathLimits[$pathPattern] = [
            'limit' => $limit,
            'window' => $window ?? $this->windowSeconds
        ];

        return $this;
    }

    /**
     * Fügt ein strengeres Limit für API-Endpunkte hinzu.
     *
     * @param int $limit Anzahl der erlaubten Anfragen
     * @param int|null $window Zeitfenster in Sekunden
     * @return self
     */
    public function withApiLimit(int $limit, ?int $window = null): self
    {
        return $this->addPathLimit('#^/api/#', $limit, $window);
    }

    /**
     * Fügt ein strengeres Limit für Authentifizierungs-Endpunkte hinzu.
     *
     * @param int $limit Anzahl der erlaubten Anfragen
     * @param int|null $window Zeitfenster in Sekunden
     * @return self
     */
    public function withAuthLimit(int $limit, ?int $window = null): self
    {
        return $this->addPathLimit('#^/(login|register|password-reset)#', $limit, $window);
    }

    /**
     * Gibt das Standard-Limit zurück.
     *
     * @return int
     */
    public function getDefaultLimit(): int
    {
        return $this->defaultLimit;
    }

    /**
     * Gibt das Standard-Zeitfenster zurück.
     *
     * @return int
     */
    public function getWindowSeconds(): int
    {
        return $this->windowSeconds;
    }

    /**
     * Gibt alle pfadspezifischen Limits zurück.
     *
     * @return array<string, array{limit: int, window: int}>
     */
    public function getPathLimits(): array
    {
        return $this->pathLimits;
    }
}
