<?php

declare(strict_types=1);

namespace App\Framework\Waf\MachineLearning;

/**
 * Types of behavioral patterns for ML analysis
 */
enum BehaviorType: string
{
    case REQUEST_FREQUENCY = 'request_frequency';
    case PATH_PATTERNS = 'path_patterns';
    case PARAMETER_PATTERNS = 'parameter_patterns';
    case USER_AGENT_PATTERNS = 'user_agent_patterns';
    case GEOGRAPHIC_PATTERNS = 'geographic_patterns';
    case TIME_PATTERNS = 'time_patterns';
    case ERROR_PATTERNS = 'error_patterns';
    case SESSION_PATTERNS = 'session_patterns';
    case PAYLOAD_PATTERNS = 'payload_patterns';
    case HEADER_PATTERNS = 'header_patterns';
    case RESPONSE_TIME_PATTERNS = 'response_time_patterns';
    case PROTOCOL_PATTERNS = 'protocol_patterns';

    /**
     * Get human-readable description
     */
    public function getDescription(): string
    {
        return match ($this) {
            self::REQUEST_FREQUENCY => 'Request frequency and rate patterns',
            self::PATH_PATTERNS => 'URL path access patterns',
            self::PARAMETER_PATTERNS => 'Parameter usage and value patterns',
            self::USER_AGENT_PATTERNS => 'User-Agent behavior patterns',
            self::GEOGRAPHIC_PATTERNS => 'Geographic location patterns',
            self::TIME_PATTERNS => 'Temporal behavior patterns',
            self::ERROR_PATTERNS => 'Error generation patterns',
            self::SESSION_PATTERNS => 'Session management patterns',
            self::PAYLOAD_PATTERNS => 'Request payload patterns',
            self::HEADER_PATTERNS => 'HTTP header usage patterns',
            self::RESPONSE_TIME_PATTERNS => 'Response time behavior patterns',
            self::PROTOCOL_PATTERNS => 'Protocol usage patterns'
        };
    }

    /**
     * Get feature extraction weight for this behavior type
     */
    public function getWeight(): float
    {
        return match ($this) {
            self::REQUEST_FREQUENCY => 0.15,
            self::PATH_PATTERNS => 0.12,
            self::PARAMETER_PATTERNS => 0.10,
            self::USER_AGENT_PATTERNS => 0.08,
            self::GEOGRAPHIC_PATTERNS => 0.08,
            self::TIME_PATTERNS => 0.10,
            self::ERROR_PATTERNS => 0.12,
            self::SESSION_PATTERNS => 0.10,
            self::PAYLOAD_PATTERNS => 0.08,
            self::HEADER_PATTERNS => 0.05,
            self::RESPONSE_TIME_PATTERNS => 0.07,
            self::PROTOCOL_PATTERNS => 0.05
        };
    }

    /**
     * Get minimum sample size needed for reliable analysis
     */
    public function getMinSampleSize(): int
    {
        return match ($this) {
            self::REQUEST_FREQUENCY => 50,
            self::PATH_PATTERNS => 30,
            self::PARAMETER_PATTERNS => 20,
            self::USER_AGENT_PATTERNS => 10,
            self::GEOGRAPHIC_PATTERNS => 15,
            self::TIME_PATTERNS => 100,
            self::ERROR_PATTERNS => 25,
            self::SESSION_PATTERNS => 40,
            self::PAYLOAD_PATTERNS => 15,
            self::HEADER_PATTERNS => 20,
            self::RESPONSE_TIME_PATTERNS => 50,
            self::PROTOCOL_PATTERNS => 10
        };
    }

    /**
     * Get analysis window duration in seconds
     */
    public function getAnalysisWindow(): int
    {
        return match ($this) {
            self::REQUEST_FREQUENCY => 300,    // 5 minutes
            self::PATH_PATTERNS => 1800,       // 30 minutes
            self::PARAMETER_PATTERNS => 900,   // 15 minutes
            self::USER_AGENT_PATTERNS => 3600, // 1 hour
            self::GEOGRAPHIC_PATTERNS => 7200, // 2 hours
            self::TIME_PATTERNS => 86400,      // 24 hours
            self::ERROR_PATTERNS => 600,       // 10 minutes
            self::SESSION_PATTERNS => 1800,    // 30 minutes
            self::PAYLOAD_PATTERNS => 900,     // 15 minutes
            self::HEADER_PATTERNS => 1800,     // 30 minutes
            self::RESPONSE_TIME_PATTERNS => 600, // 10 minutes
            self::PROTOCOL_PATTERNS => 3600    // 1 hour
        };
    }

    /**
     * Check if this behavior type requires real-time analysis
     */
    public function requiresRealTime(): bool
    {
        return match ($this) {
            self::REQUEST_FREQUENCY,
            self::ERROR_PATTERNS,
            self::RESPONSE_TIME_PATTERNS => true,
            default => false
        };
    }

    /**
     * Get all behavior types as array
     */
    public static function getAll(): array
    {
        return array_map(fn ($case) => $case->value, self::cases());
    }

    /**
     * Get real-time behavior types
     */
    public static function getRealTime(): array
    {
        return array_filter(self::cases(), fn ($case) => $case->requiresRealTime());
    }

    /**
     * Get batch analysis behavior types
     */
    public static function getBatch(): array
    {
        return array_filter(self::cases(), fn ($case) => ! $case->requiresRealTime());
    }
}
