<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * Security error codes
 *
 * Covers security violations, access control, encryption, and threat detection
 */
enum SecurityErrorCode: string implements ErrorCode
{
    case ACCESS_DENIED = 'SEC001';
    case CSRF_TOKEN_INVALID = 'SEC002';
    case ENCRYPTION_FAILED = 'SEC003';
    case DECRYPTION_FAILED = 'SEC004';
    case SIGNATURE_INVALID = 'SEC005';
    case SQL_INJECTION_DETECTED = 'SEC006';
    case XSS_DETECTED = 'SEC007';
    case PATH_TRAVERSAL_DETECTED = 'SEC008';
    case RATE_LIMIT_ABUSE = 'SEC009';
    case SUSPICIOUS_ACTIVITY = 'SEC010';

    public function getValue(): string
    {
        return $this->value;
    }

    public function getCategory(): string
    {
        return 'SEC';
    }

    public function getNumericCode(): int
    {
        return (int) substr($this->value, -3);
    }

    public function getSeverity(): ErrorSeverity
    {
        return match($this) {
            self::SQL_INJECTION_DETECTED,
            self::XSS_DETECTED,
            self::PATH_TRAVERSAL_DETECTED,
            self::ENCRYPTION_FAILED => ErrorSeverity::CRITICAL,

            self::ACCESS_DENIED,
            self::CSRF_TOKEN_INVALID,
            self::SIGNATURE_INVALID,
            self::RATE_LIMIT_ABUSE,
            self::SUSPICIOUS_ACTIVITY => ErrorSeverity::ERROR,

            self::DECRYPTION_FAILED => ErrorSeverity::WARNING,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::ACCESS_DENIED => 'Access to resource denied',
            self::CSRF_TOKEN_INVALID => 'CSRF token is invalid or expired',
            self::ENCRYPTION_FAILED => 'Data encryption operation failed',
            self::DECRYPTION_FAILED => 'Data decryption operation failed',
            self::SIGNATURE_INVALID => 'Digital signature verification failed',
            self::SQL_INJECTION_DETECTED => 'SQL injection attempt detected',
            self::XSS_DETECTED => 'Cross-site scripting attempt detected',
            self::PATH_TRAVERSAL_DETECTED => 'Path traversal attempt detected',
            self::RATE_LIMIT_ABUSE => 'Rate limit abuse detected',
            self::SUSPICIOUS_ACTIVITY => 'Suspicious activity pattern detected',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::ACCESS_DENIED => 'Request proper authorization or permissions',
            self::CSRF_TOKEN_INVALID => 'Refresh page to obtain new CSRF token',
            self::ENCRYPTION_FAILED => 'Check encryption configuration and keys',
            self::DECRYPTION_FAILED => 'Verify encryption key and data integrity',
            self::SIGNATURE_INVALID => 'Verify signature and signing key',
            self::SQL_INJECTION_DETECTED => 'Input sanitization required - contact support',
            self::XSS_DETECTED => 'Input sanitization required - contact support',
            self::PATH_TRAVERSAL_DETECTED => 'Use valid resource paths only',
            self::RATE_LIMIT_ABUSE => 'Reduce request frequency significantly',
            self::SUSPICIOUS_ACTIVITY => 'Contact support if you believe this is an error',
        };
    }

    public function isRecoverable(): bool
    {
        return match($this) {
            self::SQL_INJECTION_DETECTED,
            self::XSS_DETECTED,
            self::PATH_TRAVERSAL_DETECTED => false,
            default => true,
        };
    }

    public function getRetryAfterSeconds(): ?int
    {
        return match($this) {
            self::CSRF_TOKEN_INVALID => 0,
            self::RATE_LIMIT_ABUSE => 300,
            default => null,
        };
    }
}
