<?php

declare(strict_types=1);

namespace App\Framework\Waf\Analysis;

/**
 * Types of request analysis that can be performed
 */
enum AnalysisType: string
{
    case HEADERS = 'headers';
    case BODY = 'body';
    case PARAMETERS = 'parameters';
    case COOKIES = 'cookies';
    case URL = 'url';
    case METHOD = 'method';
    case PROTOCOL = 'protocol';
    case SIZE = 'size';
    case ENCODING = 'encoding';
    case CONTENT_TYPE = 'content_type';
    case USER_AGENT = 'user_agent';
    case REFERRER = 'referrer';
    case FILES = 'files';
    case JSON = 'json';
    case XML = 'xml';

    /**
     * Get analysis description
     */
    public function getDescription(): string
    {
        return match ($this) {
            self::HEADERS => 'HTTP headers analysis and validation',
            self::BODY => 'Request body content analysis',
            self::PARAMETERS => 'Query and form parameters analysis',
            self::COOKIES => 'Cookie values and structure analysis',
            self::URL => 'URL path and structure analysis',
            self::METHOD => 'HTTP method validation',
            self::PROTOCOL => 'HTTP protocol compliance analysis',
            self::SIZE => 'Request size and limits analysis',
            self::ENCODING => 'Content encoding and character set analysis',
            self::CONTENT_TYPE => 'Content-Type header validation',
            self::USER_AGENT => 'User-Agent string analysis',
            self::REFERRER => 'Referrer header analysis',
            self::FILES => 'File upload analysis',
            self::JSON => 'JSON payload structure analysis',
            self::XML => 'XML payload structure analysis'
        };
    }

    /**
     * Get processing priority (higher = earlier processing)
     */
    public function getPriority(): int
    {
        return match ($this) {
            self::METHOD => 100,        // Validate method first
            self::PROTOCOL => 95,       // Protocol compliance
            self::SIZE => 90,           // Size limits before content parsing
            self::HEADERS => 85,        // Header validation
            self::CONTENT_TYPE => 80,   // Content type before body parsing
            self::URL => 75,            // URL structure
            self::USER_AGENT => 70,     // User agent validation
            self::REFERRER => 65,       // Referrer validation
            self::ENCODING => 60,       // Encoding validation
            self::COOKIES => 55,        // Cookie analysis
            self::PARAMETERS => 50,     // Parameter analysis
            self::FILES => 45,          // File upload analysis
            self::BODY => 40,           // Body content analysis
            self::JSON => 35,           // JSON structure (after body)
            self::XML => 30             // XML structure (after body)
        };
    }

    /**
     * Check if analysis requires request body
     */
    public function requiresBody(): bool
    {
        return match ($this) {
            self::BODY, self::JSON, self::XML, self::FILES => true,
            default => false
        };
    }

    /**
     * Check if analysis is computationally expensive
     */
    public function isExpensive(): bool
    {
        return match ($this) {
            self::BODY, self::JSON, self::XML, self::FILES => true,
            default => false
        };
    }

    /**
     * Get expected processing time category
     */
    public function getProcessingTimeCategory(): string
    {
        return match ($this) {
            self::METHOD, self::PROTOCOL, self::SIZE => 'fast',
            self::HEADERS, self::URL, self::COOKIES, self::PARAMETERS => 'medium',
            self::BODY, self::JSON, self::XML, self::FILES => 'slow',
            default => 'medium'
        };
    }

    /**
     * Check if analysis can run in parallel
     */
    public function canRunInParallel(): bool
    {
        return match ($this) {
            // These can run independently
            self::HEADERS, self::USER_AGENT, self::REFERRER, self::COOKIES,
            self::URL, self::PARAMETERS => true,
            // These need sequential processing
            self::CONTENT_TYPE, self::BODY, self::JSON, self::XML, self::FILES => false,
            default => true
        };
    }

    /**
     * Get analysis dependencies (must run before this analysis)
     */
    public function getDependencies(): array
    {
        return match ($this) {
            self::BODY => [self::CONTENT_TYPE, self::SIZE],
            self::JSON => [self::BODY, self::CONTENT_TYPE],
            self::XML => [self::BODY, self::CONTENT_TYPE],
            self::FILES => [self::BODY, self::CONTENT_TYPE, self::SIZE],
            self::PARAMETERS => [self::BODY], // Form parameters need body
            default => []
        };
    }

    /**
     * Check if analysis applies to specific content type
     */
    public function appliesToContentType(?string $contentType): bool
    {
        if ($contentType === null) {
            return ! $this->requiresBody();
        }

        $contentType = strtolower($contentType);

        return match ($this) {
            self::JSON => str_contains($contentType, 'application/json'),
            self::XML => str_contains($contentType, 'application/xml') ||
                        str_contains($contentType, 'text/xml'),
            self::FILES => str_contains($contentType, 'multipart/form-data'),
            self::PARAMETERS => str_contains($contentType, 'application/x-www-form-urlencoded') ||
                               str_contains($contentType, 'multipart/form-data'),
            // These apply to all content types
            self::HEADERS, self::URL, self::METHOD, self::PROTOCOL,
            self::SIZE, self::COOKIES, self::USER_AGENT, self::REFERRER,
            self::CONTENT_TYPE, self::ENCODING => true,
            // Body analysis applies to all content types
            self::BODY => true,
            default => false
        };
    }

    /**
     * Get maximum safe processing time in milliseconds
     */
    public function getMaxProcessingTime(): int
    {
        return match ($this) {
            self::METHOD, self::PROTOCOL => 10,
            self::SIZE, self::HEADERS, self::URL => 50,
            self::COOKIES, self::PARAMETERS, self::USER_AGENT,
            self::REFERRER, self::CONTENT_TYPE, self::ENCODING => 100,
            self::BODY => 500,
            self::JSON, self::XML => 1000,
            self::FILES => 2000
        };
    }

    /**
     * Check if analysis should be cached
     */
    public function shouldCache(): bool
    {
        return match ($this) {
            // Cache expensive analyses
            self::BODY, self::JSON, self::XML, self::FILES => true,
            // Cache user agent analysis (frequently repeated)
            self::USER_AGENT => true,
            default => false
        };
    }
}
