<?php

declare(strict_types=1);

namespace App\Framework\DDoS\Waf;

use App\Framework\Cache\Cache;
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Core\ValueObjects\Percentage;
use App\Framework\DateTime\Clock;
use App\Framework\Http\HttpRequest;
use App\Framework\Http\Request;
use App\Framework\Logging\Logger;
use App\Framework\Waf\DetectionCategory;
use App\Framework\Waf\DetectionSeverity;
use App\Framework\Waf\LayerResult;
use App\Framework\Waf\Layers\LayerInterface;
use App\Framework\Waf\ValueObjects\Detection;
use App\Framework\Waf\ValueObjects\DetectionCollection;
use App\Framework\Waf\ValueObjects\LayerConfig;
use App\Framework\Waf\ValueObjects\LayerMetrics;

/**
 * DDoS-specific WAF Layer - Integrates with existing WAF infrastructure
 *
 * Detects Layer 7 DDoS attack patterns that complement the main DDoS protection engine.
 * This layer focuses on application-specific attack patterns that traditional
 * volumetric detection might miss.
 */
final class DDoSWafLayer implements LayerInterface
{
    private const string LAYER_NAME = 'ddos_application_layer';
    private const string CACHE_PREFIX = 'ddos_waf:';

    // Application-layer DDoS patterns
    /** @var array<string> */
    private const array RESOURCE_INTENSIVE_PATTERNS = [
        '\/search\?',
        '\/export',
        '\/report',
        '\/admin\/',
        '\/api\/.*?\/search',
        '\.pdf$',
        '\.zip$',
        '\/backup',
        '\/logs?\/',
    ];

    // Suspicious query patterns
    /** @var array<string> */
    private const array SUSPICIOUS_QUERY_PATTERNS = [
        'union\s+select',
        'sleep\s*\(',
        'benchmark\s*\(',
        'load_file\s*\(',
        'into\s+outfile',
        'waitfor\s+delay',
        'pg_sleep\s*\(',
        'dbms_pipe\.receive_message',
    ];

    // Bot/automation indicators in User-Agent
    /** @var array<string> */
    private const array BOT_USER_AGENT_PATTERNS = [
        'bot',
        'crawler',
        'spider',
        'scraper',
        'python',
        'curl',
        'wget',
        'postman',
        'http',
        'automated',
        'test',
    ];

    private LayerConfig $layerConfig;

    private LayerMetrics $metrics;

    public function __construct(
        private readonly Cache $cache,
        private readonly Clock $clock,
        private readonly Logger $logger,
        private readonly DDoSWafConfig $config = new DDoSWafConfig(),
        ?LayerConfig $layerConfig = null
    ) {
        $this->layerConfig = $layerConfig ?? LayerConfig::default();
        $this->metrics = LayerMetrics::empty();
    }

    public function getName(): string
    {
        return self::LAYER_NAME;
    }

    public function isEnabled(): bool
    {
        return $this->config->enabled;
    }

    public function isHealthy(): bool
    {
        // Check if cache is responsive
        try {
            $healthKey = $this->generateKey('health', 'check');
            $this->cache->set($healthKey, time(), 5);
            $this->cache->get($healthKey);

            return true;
        } catch (\Throwable $e) {
            $this->logger->warning('DDoS WAF layer health check failed', [
                'error' => $e->getMessage(),
            ]);

            return false;
        }
    }

    public function analyze(Request $request): LayerResult
    {
        if (! $request instanceof HttpRequest) {
            $this->metrics = $this->metrics->recordRequest(Duration::zero(), false);

            return LayerResult::neutral(self::LAYER_NAME, 'Not an HTTP request');
        }

        $analysisStart = $this->clock->time();
        $detections = new DetectionCollection();
        $threatDetected = false;

        try {
            // Perform different types of application-layer DDoS detection
            $this->detectResourceIntensiveRequests($request, $detections);
            $this->detectSlowlorisAttacks($request, $detections);
            $this->detectHttpFloodPatterns($request, $detections);
            $this->detectBotAutomation($request, $detections);
            $this->detectQueryComplexity($request, $detections);
            $this->detectProtocolAbusePatterns($request, $detections);
            $this->detectRepetitivePatterns($request, $detections);

            // Calculate overall threat score
            $threatScore = $this->calculateThreatScore($detections);
            $confidence = $this->calculateConfidence($detections, $request);

            // Update learning patterns
            $this->updateLearningPatterns($request, $detections);

            $processingTime = $this->clock->time()->diff($analysisStart);
            $threatDetected = ! $detections->isEmpty();

            // Update metrics
            $this->metrics = $this->metrics->recordRequest($processingTime, $threatDetected);

            // Create result based on findings
            $result = $this->createLayerResult($detections, $threatScore, $confidence);

            return $result->withExecutionDuration($processingTime);

        } catch (\Throwable $e) {
            $processingTime = $this->clock->time()->diff($analysisStart);
            $this->metrics = $this->metrics->recordError();

            $this->logger->error('DDoS WAF layer analysis failed', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'request_path' => $request->path,
            ]);

            return LayerResult::neutral(self::LAYER_NAME, 'Analysis failed: ' . $e->getMessage());
        }
    }

    /**
     * Detect requests targeting resource-intensive operations
     */
    private function detectResourceIntensiveRequests(HttpRequest $request, DetectionCollection $detections): void
    {
        $path = $request->path;
        $query = $request->queryString ?? '';

        foreach (self::RESOURCE_INTENSIVE_PATTERNS as $pattern) {
            if (preg_match("/{$pattern}/i", $path . '?' . $query)) {
                // Check if this IP is making too many resource-intensive requests
                $clientIp = $this->getClientIp($request);
                $intensiveKey = $this->generateKey('intensive', $clientIp);

                $intensiveCount = $this->cache->get($intensiveKey, 0) + 1;
                $this->cache->set($intensiveKey, $intensiveCount, Duration::fromMinutes(5)->toCacheSeconds());

                if ($intensiveCount > $this->config->maxResourceIntensiveRequestsPerMinute) {
                    $detections->add(new Detection(
                        category: DetectionCategory::APPLICATION_ABUSE,
                        severity: DetectionSeverity::HIGH,
                        message: "Excessive resource-intensive requests detected",
                        confidence: min(1.0, $intensiveCount / ($this->config->maxResourceIntensiveRequestsPerMinute * 2)),
                        evidence: [
                            /** @var array<string, mixed> */
                            'pattern' => $pattern,
                            'path' => $path,
                            'count_per_5min' => $intensiveCount,
                            'threshold' => $this->config->maxResourceIntensiveRequestsPerMinute,
                        ]
                    ));
                }

                break;
            }
        }
    }

    /**
     * Detect Slowloris-style attacks (slow HTTP connections)
     */
    private function detectSlowlorisAttacks(HttpRequest $request, DetectionCollection $detections): void
    {
        $clientIp = $this->getClientIp($request);
        $connectionKey = $this->generateKey('connections', $clientIp);

        // Track connection patterns
        /** @var array{connection_times: array<float>, incomplete_requests: int, slow_requests: int} */
        $connectionData = $this->cache->get($connectionKey, [
            'connection_times' => [],
            'incomplete_requests' => 0,
            'slow_requests' => 0,
        ]);

        $now = $this->clock->time()->toFloat();
        $connectionData['connection_times'][] = $now;

        // Keep only recent connections (last 5 minutes)
        $fiveMinutesAgo = $now - 300;
        $connectionData['connection_times'] = array_filter(
            $connectionData['connection_times'],
            fn ($time) => $time > $fiveMinutesAgo
        );

        // Detect slow connection patterns
        $connectionCount = count($connectionData['connection_times']);
        $avgInterval = $this->calculateAverageInterval($connectionData['connection_times']);

        // Suspicious if many slow connections from same IP
        if ($connectionCount > $this->config->maxSlowConnectionsPerIp && $avgInterval > 10) {
            $detections->add(new Detection(
                category: DetectionCategory::DOS_ATTACK,
                severity: DetectionSeverity::HIGH,
                message: "Slowloris attack pattern detected",
                confidence: min(1.0, $connectionCount / ($this->config->maxSlowConnectionsPerIp * 2)),
                evidence: /** @var array<string, mixed> */ [
                    'connection_count' => $connectionCount,
                    'average_interval' => $avgInterval,
                    'threshold' => $this->config->maxSlowConnectionsPerIp,
                ]
            ));
        }

        $this->cache->set($connectionKey, $connectionData, Duration::fromMinutes(10)->toCacheSeconds());
    }

    /**
     * Detect HTTP flood patterns
     */
    private function detectHttpFloodPatterns(HttpRequest $request, DetectionCollection $detections): void
    {
        $clientIp = $this->getClientIp($request);
        $floodKey = $this->generateKey('flood', $clientIp);

        // Track request patterns
        /** @var array{request_count: int, unique_paths: array<string>, methods: array<string>, start_time: float} */
        $floodData = $this->cache->get($floodKey, [
            'request_count' => 0,
            'unique_paths' => [],
            'methods' => [],
            'start_time' => $this->clock->time()->toFloat(),
        ]);

        $floodData['request_count']++;
        $floodData['unique_paths'][] = $request->path;
        $floodData['methods'][] = $request->method->value;

        // Keep only unique values and limit size
        $floodData['unique_paths'] = array_unique(array_slice($floodData['unique_paths'], -20));
        $floodData['methods'] = array_slice($floodData['methods'], -20);

        $timeWindow = $this->clock->time()->toFloat() - $floodData['start_time'];
        $requestRate = $timeWindow > 0 ? $floodData['request_count'] / ($timeWindow / 60) : 0;

        // Detect flood patterns
        $pathDiversity = count($floodData['unique_paths']);
        $methodDiversity = count(array_unique($floodData['methods']));

        // High request rate with low diversity = HTTP flood
        if ($requestRate > $this->config->httpFloodThreshold &&
            $pathDiversity < 3 &&
            $methodDiversity < 3) {

            $detections->add(new Detection(
                category: DetectionCategory::DOS_ATTACK,
                severity: DetectionSeverity::CRITICAL,
                message: "HTTP flood attack detected",
                confidence: min(1.0, $requestRate / ($this->config->httpFloodThreshold * 2)),
                evidence: [
                    'request_rate_per_minute' => $requestRate,
                    'path_diversity' => $pathDiversity,
                    'method_diversity' => $methodDiversity,
                    'total_requests' => $floodData['request_count'],
                    'time_window_seconds' => $timeWindow,
                ]
            ));
        }

        // Reset if window is too old
        if ($timeWindow > 300) { // 5 minutes
            $floodData = [
                'request_count' => 1,
                'unique_paths' => [$request->path],
                'methods' => [$request->method->value],
                'start_time' => $this->clock->time()->toFloat(),
            ];
        }

        $this->cache->set($floodKey, $floodData, Duration::fromMinutes(10)->toCacheSeconds());
    }

    /**
     * Detect bot/automation patterns
     */
    private function detectBotAutomation(HttpRequest $request, DetectionCollection $detections): void
    {
        $userAgent = $request->headers->get('User-Agent', '');
        $clientIp = $this->getClientIp($request);

        // Check User-Agent patterns
        $botScore = 0.0;
        foreach (self::BOT_USER_AGENT_PATTERNS as $pattern) {
            if (stripos($userAgent, $pattern) !== false) {
                $botScore += 0.2;
            }
        }

        // Check missing or suspicious headers
        $expectedHeaders = ['Accept', 'Accept-Language', 'Accept-Encoding'];
        $missingHeaders = 0;
        foreach ($expectedHeaders as $header) {
            if (! $request->headers->has($header)) {
                $missingHeaders++;
                $botScore += 0.15;
            }
        }

        // Check request timing patterns
        $timingKey = $this->generateKey('timing', $clientIp);
        $timingData = $this->cache->get($timingKey, ['intervals' => []]);

        $now = $this->clock->time()->toFloat();
        $timingData['intervals'][] = $now;

        // Keep only recent intervals
        $timingData['intervals'] = array_filter(
            $timingData['intervals'],
            fn ($time) => $time > ($now - 300) // Last 5 minutes
        );

        // Calculate timing regularity
        if (count($timingData['intervals']) >= 5) {
            $intervals = [];
            $times = array_values($timingData['intervals']);
            for ($i = 1; $i < count($times); $i++) {
                $intervals[] = $times[$i] - $times[$i - 1];
            }

            $avgInterval = array_sum($intervals) / count($intervals);
            $variance = array_sum(array_map(fn ($x) => pow($x - $avgInterval, 2), $intervals)) / count($intervals);
            $stdDev = sqrt($variance);

            // Regular timing suggests automation
            if ($avgInterval > 0 && ($stdDev / $avgInterval) < 0.1) {
                $botScore += 0.3;
            }
        }

        $this->cache->set($timingKey, $timingData, Duration::fromMinutes(10)->toCacheSeconds());

        if ($botScore >= $this->config->botDetectionThreshold) {
            $detections->add(new Detection(
                category: DetectionCategory::BOT_DETECTION,
                severity: DetectionSeverity::MEDIUM,
                message: "Automated bot behavior detected",
                confidence: min(1.0, $botScore),
                evidence: [
                    'bot_score' => $botScore,
                    'user_agent' => $userAgent,
                    'missing_headers' => $missingHeaders,
                    'timing_regularity' => isset($stdDev) ? ($stdDev / $avgInterval) : null,
                ]
            ));
        }
    }

    /**
     * Detect complex query patterns that could cause database stress
     */
    private function detectQueryComplexity(HttpRequest $request, DetectionCollection $detections): void
    {
        $query = $request->queryString ?? '';
        $body = $request->getBody() ?? '';
        $content = $query . ' ' . $body;

        $suspiciousCount = 0;
        /** @var array<string> */
        $matchedPatterns = [];

        foreach (self::SUSPICIOUS_QUERY_PATTERNS as $pattern) {
            if (preg_match("/{$pattern}/i", $content)) {
                $suspiciousCount++;
                $matchedPatterns[] = $pattern;
            }
        }

        // Check for excessively long queries
        $queryLength = strlen($content);
        if ($queryLength > $this->config->maxQueryLength) {
            $suspiciousCount++;
            $matchedPatterns[] = 'excessive_query_length';
        }

        // Check for multiple SQL injection attempts
        /** @var array<string> */
        $sqlKeywords = ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'DROP', 'CREATE', 'ALTER'];
        $sqlCount = 0;
        foreach ($sqlKeywords as $keyword) {
            $sqlCount += substr_count(strtoupper($content), $keyword);
        }

        if ($sqlCount > 3) {
            $suspiciousCount++;
            $matchedPatterns[] = 'multiple_sql_keywords';
        }

        if ($suspiciousCount > 0) {
            $severity = $suspiciousCount >= 3 ? DetectionSeverity::CRITICAL :
                       ($suspiciousCount >= 2 ? DetectionSeverity::HIGH : DetectionSeverity::MEDIUM);

            $detections->add(new Detection(
                category: DetectionCategory::SQL_INJECTION,
                severity: $severity,
                message: "Complex query pattern detected - potential database stress attack",
                confidence: min(1.0, $suspiciousCount / 5),
                evidence: /** @var array<string, mixed> */ [
                    'suspicious_patterns' => $matchedPatterns,
                    'pattern_count' => $suspiciousCount,
                    'query_length' => $queryLength,
                    'sql_keyword_count' => $sqlCount,
                ]
            ));
        }
    }

    /**
     * Detect HTTP protocol abuse patterns
     */
    private function detectProtocolAbusePatterns(HttpRequest $request, DetectionCollection $detections): void
    {
        $clientIp = $this->getClientIp($request);
        $headers = $request->headers->all();

        $abuseScore = 0.0;
        /** @var array<string> */
        $abusePatterns = [];

        // Check for header anomalies
        $headerCount = count($headers);
        if ($headerCount > 50) {
            $abuseScore += 0.3;
            $abusePatterns[] = 'excessive_headers';
        }

        // Check for malformed headers
        foreach ($headers as $name => $value) {
            if (strlen($name) > 100 || strlen($value) > 8192) {
                $abuseScore += 0.2;
                $abusePatterns[] = 'oversized_header';

                break;
            }
        }

        // Check HTTP method abuse
        $method = $request->method->value;
        if (in_array($method, ['TRACE', 'CONNECT', 'OPTIONS'])) {
            $methodKey = $this->generateKey('method_abuse', $clientIp . ':' . $method);
            $methodCount = $this->cache->get($methodKey, 0) + 1;
            $this->cache->set($methodKey, $methodCount, Duration::fromMinutes(5)->toCacheSeconds());

            if ($methodCount > 10) {
                $abuseScore += 0.4;
                $abusePatterns[] = 'method_abuse_' . strtolower($method);
            }
        }

        // Check for HTTP version anomalies
        $httpVersion = $request->server->get('SERVER_PROTOCOL', 'HTTP/1.1');
        if (! in_array($httpVersion, ['HTTP/1.0', 'HTTP/1.1', 'HTTP/2.0'])) {
            $abuseScore += 0.2;
            $abusePatterns[] = 'invalid_http_version';
        }

        if ($abuseScore >= $this->config->protocolAbuseThreshold) {
            $detections->add(new Detection(
                category: DetectionCategory::PROTOCOL_VIOLATION,
                severity: DetectionSeverity::MEDIUM,
                message: "HTTP protocol abuse detected",
                confidence: min(1.0, $abuseScore),
                evidence: [
                    'abuse_score' => $abuseScore,
                    'abuse_patterns' => $abusePatterns,
                    'header_count' => $headerCount,
                    'http_method' => $method,
                    'http_version' => $httpVersion,
                ]
            ));
        }
    }

    /**
     * Detect repetitive attack patterns
     */
    private function detectRepetitivePatterns(HttpRequest $request, DetectionCollection $detections): void
    {
        $clientIp = $this->getClientIp($request);
        $requestSignature = hash('sha256', $request->path . '|' . ($request->queryString ?? '') . '|' . $request->method->value);

        $repetitiveKey = $this->generateKey('repetitive', $clientIp);
        $repetitiveData = $this->cache->get($repetitiveKey, ['signatures' => [], 'counts' => []]);

        // Track request signatures
        if (! isset($repetitiveData['counts'][$requestSignature])) {
            $repetitiveData['counts'][$requestSignature] = 0;
        }
        $repetitiveData['counts'][$requestSignature]++;

        // Keep only recent signatures (prevent memory bloat)
        if (count($repetitiveData['counts']) > 100) {
            $repetitiveData['counts'] = array_slice($repetitiveData['counts'], -50, null, true);
        }

        // Find most repeated signature
        $maxRepeats = max($repetitiveData['counts']);
        $totalRequests = array_sum($repetitiveData['counts']);
        $repetitionRatio = $totalRequests > 0 ? $maxRepeats / $totalRequests : 0;

        if ($maxRepeats > $this->config->maxRepetitiveRequests || $repetitionRatio > 0.8) {
            $detections->add(new Detection(
                category: DetectionCategory::DOS_ATTACK,
                severity: DetectionSeverity::HIGH,
                message: "Repetitive request pattern detected",
                confidence: min(1.0, $maxRepeats / ($this->config->maxRepetitiveRequests * 2)),
                evidence: [
                    'max_repeats' => $maxRepeats,
                    'repetition_ratio' => $repetitionRatio,
                    'total_requests' => $totalRequests,
                    'unique_signatures' => count($repetitiveData['counts']),
                    'request_signature' => $requestSignature,
                ]
            ));
        }

        $this->cache->set($repetitiveKey, $repetitiveData, Duration::fromMinutes(10)->toCacheSeconds());
    }

    private function calculateThreatScore(DetectionCollection $detections): float
    {
        if ($detections->isEmpty()) {
            return 0.0;
        }

        $totalScore = 0.0;
        $totalWeight = 0.0;

        foreach ($detections->getAll() as $detection) {
            $weight = match ($detection->severity) {
                DetectionSeverity::CRITICAL => 1.0,
                DetectionSeverity::HIGH => 0.8,
                DetectionSeverity::MEDIUM => 0.6,
                DetectionSeverity::LOW => 0.4,
                DetectionSeverity::INFO => 0.2
            };

            $totalScore += $detection->confidence * $weight;
            $totalWeight += $weight;
        }

        return $totalWeight > 0 ? min(1.0, $totalScore / $totalWeight) : 0.0;
    }

    private function calculateConfidence(DetectionCollection $detections, HttpRequest $request): float
    {
        if ($detections->isEmpty()) {
            return 0.0;
        }

        $confidenceFactors = [];

        // Base confidence from detections
        $avgConfidence = 0.0;
        foreach ($detections->getAll() as $detection) {
            $avgConfidence += $detection->confidence;
        }
        $avgConfidence /= $detections->count();
        $confidenceFactors[] = $avgConfidence;

        // Multiple detection types increase confidence
        $categories = [];
        foreach ($detections->getAll() as $detection) {
            $categories[] = $detection->category;
        }
        $uniqueCategories = count(array_unique($categories));
        $categoryConfidence = min(1.0, $uniqueCategories / 3); // Max 3 categories
        $confidenceFactors[] = $categoryConfidence;

        // Known client IP patterns
        $clientIp = $this->getClientIp($request);
        $historyKey = $this->generateKey('history', $clientIp);
        $history = $this->cache->get($historyKey, ['attack_count' => 0, 'total_requests' => 0]);

        if ($history['total_requests'] > 10) {
            $attackRatio = $history['attack_count'] / $history['total_requests'];
            $confidenceFactors[] = min(1.0, $attackRatio * 2); // Scale attack history
        }

        return array_sum($confidenceFactors) / count($confidenceFactors);
    }

    private function createLayerResult(DetectionCollection $detections, float $threatScore, float $confidence): LayerResult
    {
        if ($detections->isEmpty()) {
            return LayerResult::pass(self::LAYER_NAME, 'No DDoS patterns detected');
        }

        $criticalDetections = array_filter(
            $detections->getAll(),
            fn ($d) => $d->severity === DetectionSeverity::CRITICAL
        );

        if (! empty($criticalDetections) || $threatScore >= 0.8) {
            return LayerResult::block(
                self::LAYER_NAME,
                'Critical DDoS attack patterns detected',
                $detections
            );
        }

        if ($threatScore >= 0.6) {
            return LayerResult::suspicious(
                self::LAYER_NAME,
                'Suspicious DDoS patterns detected',
                $detections
            );
        }

        return LayerResult::pass(
            self::LAYER_NAME,
            'Minor DDoS indicators detected',
            $detections
        );
    }

    private function updateLearningPatterns(HttpRequest $request, DetectionCollection $detections): void
    {
        $clientIp = $this->getClientIp($request);
        $learningKey = $this->generateKey('learning', $clientIp);

        $learning = $this->cache->get($learningKey, [
            'request_patterns' => [],
            'attack_indicators' => [],
            'false_positives' => 0,
            'confirmed_attacks' => 0,
        ]);

        // Store request patterns for learning
        $pattern = [
            'path' => $request->path,
            'method' => $request->method->value,
            'user_agent' => $request->headers->get('User-Agent', ''),
            'detections' => $detections->count(),
            'timestamp' => $this->clock->time()->toFloat(),
        ];

        $learning['request_patterns'][] = $pattern;

        // Limit learning data size
        if (count($learning['request_patterns']) > 50) {
            $learning['request_patterns'] = array_slice($learning['request_patterns'], -25);
        }

        $this->cache->set($learningKey, $learning, Duration::fromDays(1)->toCacheSeconds());
    }

    private function getClientIp(HttpRequest $request): string
    {
        return $request->server->getClientIp()?->value ?? '127.0.0.1';
    }

    private function generateKey(string $type, string $identifier): string
    {
        return self::CACHE_PREFIX . $type . ':' . hash('sha256', $identifier);
    }

    private function calculateAverageInterval(array $timestamps): float
    {
        if (count($timestamps) < 2) {
            return 0.0;
        }

        sort($timestamps);
        $intervals = [];

        for ($i = 1; $i < count($timestamps); $i++) {
            $intervals[] = $timestamps[$i] - $timestamps[$i - 1];
        }

        return array_sum($intervals) / count($intervals);
    }

    // ============================================
    // LayerInterface Implementation
    // ============================================

    public function getPriority(): int
    {
        return 500; // Medium priority - after input validation but before main WAF rules
    }

    public function getConfidenceLevel(): Percentage
    {
        return Percentage::from(85.0); // High confidence in DDoS detection
    }

    public function getTimeoutThreshold(): Duration
    {
        return $this->layerConfig->getEffectiveTimeout();
    }

    public function configure(LayerConfig $config): void
    {
        $this->layerConfig = $config;
    }

    public function getConfig(): LayerConfig
    {
        return $this->layerConfig;
    }

    public function getMetrics(): LayerMetrics
    {
        return $this->metrics;
    }

    public function reset(): void
    {
        $this->metrics = LayerMetrics::empty();

        // Clear all cache entries for this layer
        $cacheKeys = [
            'health', 'monitoring', 'intensive', 'connections', 'flood',
            'timing', 'repetitive', 'learning', 'history', 'baseline',
        ];

        foreach ($cacheKeys as $keyType) {
            // Note: This is a simplified approach - in practice you might want
            // a more sophisticated cache clearing mechanism
            try {
                $key = $this->generateKey($keyType, 'reset_all');
                $this->cache->forget($key);
            } catch (\Throwable $e) {
                $this->logger->debug('Failed to clear cache key during reset', [
                    'key_type' => $keyType,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        $this->logger->info('DDoS WAF layer reset completed');
    }

    public function warmUp(): void
    {
        // Pre-load common patterns and initialize baseline data
        $this->logger->info('DDoS WAF layer warming up');

        try {
            // Initialize baseline data structure
            $baselineKey = $this->generateKey('baseline', 'geographic');
            if (! $this->cache->get($baselineKey)) {
                $baseline = [
                    'country_frequency' => [],
                    'total_requests' => 0,
                    'last_updated' => $this->clock->time()->toFloat(),
                ];
                $this->cache->set($baselineKey, $baseline, Duration::fromDays(7)->toCacheSeconds());
            }

            // Pre-compile regex patterns for better performance
            foreach (self::RESOURCE_INTENSIVE_PATTERNS as $pattern) {
                // Test pattern compilation
                @preg_match("/{$pattern}/i", '');
            }

            foreach (self::SUSPICIOUS_QUERY_PATTERNS as $pattern) {
                // Test pattern compilation
                @preg_match("/{$pattern}/i", '');
            }

            $this->logger->info('DDoS WAF layer warm-up completed');

        } catch (\Throwable $e) {
            $this->logger->warning('DDoS WAF layer warm-up failed', [
                'error' => $e->getMessage(),
            ]);
        }
    }

    public function shutdown(): void
    {
        $this->logger->info('DDoS WAF layer shutting down');

        // Save final metrics if needed
        $finalMetrics = $this->metrics->toArray();
        $this->logger->info('DDoS WAF layer final metrics', $finalMetrics);

        // Could persist learning data here if needed
        $this->logger->info('DDoS WAF layer shutdown completed');
    }

    public function getDependencies(): array
    {
        // This layer doesn't depend on other WAF layers
        return [];
    }

    public function supportsParallelProcessing(): bool
    {
        return true; // This layer can be processed in parallel with others
    }

    public function getVersion(): string
    {
        return '1.0.0';
    }

    public function getSupportedCategories(): array
    {
        return [
            DetectionCategory::DOS_ATTACK,
            DetectionCategory::DDOS_ATTACK,
            DetectionCategory::MALICIOUS_BOT,
            DetectionCategory::AUTOMATED_ATTACK,
            DetectionCategory::RATE_LIMIT_VIOLATION,
            DetectionCategory::HTTP_PROTOCOL_VIOLATION,
            DetectionCategory::SUSPICIOUS_USER_AGENT,
            DetectionCategory::ANOMALOUS_BEHAVIOR,
            DetectionCategory::SQL_INJECTION, // For query complexity detection
            DetectionCategory::APPLICATION_ABUSE, // For resource-intensive requests
        ];
    }
}
