<?php

declare(strict_types=1);

namespace App\Framework\Logging\Aggregation;

use App\Framework\Logging\LogLevel;

/**
 * Aggregation Configuration
 *
 * Definiert welche Logs aggregiert werden sollen.
 */
final readonly class AggregationConfig
{
    /**
     * @param int $flushIntervalSeconds Nach wie vielen Sekunden werden aggregierte Logs ausgegeben
     * @param int $maxEntriesPerWindow Maximale Anzahl verschiedener Logs im Window
     * @param LogLevel[] $levelsToAggregate Welche Log-Levels aggregiert werden
     * @param int $minOccurrencesForAggregation Mindestanzahl bevor aggregiert wird
     */
    public function __construct(
        public int $flushIntervalSeconds = 60,
        public int $maxEntriesPerWindow = 1000,
        public array $levelsToAggregate = [],
        public int $minOccurrencesForAggregation = 2
    ) {
    }

    /**
     * Standard Production Config
     */
    public static function production(): self
    {
        return new self(
            flushIntervalSeconds: 60,
            maxEntriesPerWindow: 1000,
            levelsToAggregate: [
                LogLevel::INFO,
                LogLevel::NOTICE,
                LogLevel::WARNING,
            ],
            minOccurrencesForAggregation: 3
        );
    }

    /**
     * Aggressive Aggregation für High-Volume
     */
    public static function aggressive(): self
    {
        return new self(
            flushIntervalSeconds: 300, // 5 Minuten
            maxEntriesPerWindow: 500,
            levelsToAggregate: [
                LogLevel::DEBUG,
                LogLevel::INFO,
                LogLevel::NOTICE,
                LogLevel::WARNING,
            ],
            minOccurrencesForAggregation: 2
        );
    }

    /**
     * Keine Aggregation
     */
    public static function disabled(): self
    {
        return new self(
            levelsToAggregate: []
        );
    }

    /**
     * Prüft ob Level aggregiert werden soll
     */
    public function shouldAggregate(LogLevel $level): bool
    {
        foreach ($this->levelsToAggregate as $aggregateLevel) {
            if ($level === $aggregateLevel) {
                return true;
            }
        }

        return false;
    }
}
