<?php

declare(strict_types=1);

namespace App\Framework\Discovery\ValueObjects;

/**
 * Compression level enumeration for cache data compression
 *
 * Defines different compression strategies with trade-offs between
 * compression ratio and CPU usage.
 */
enum CompressionLevel: string
{
    case NONE = 'none';         // No compression
    case LOW = 'low';           // Fast compression, lower ratio
    case MEDIUM = 'medium';     // Balanced compression
    case HIGH = 'high';         // Good compression, higher CPU
    case MAXIMUM = 'maximum';   // Best compression, highest CPU

    /**
     * Get the gzip compression level integer
     */
    public function getGzipLevel(): int
    {
        return match ($this) {
            self::NONE => 0,
            self::LOW => 1,
            self::MEDIUM => 6,
            self::HIGH => 8,
            self::MAXIMUM => 9
        };
    }

    /**
     * Get expected compression ratio (approximate)
     */
    public function getExpectedRatio(): float
    {
        return match ($this) {
            self::NONE => 1.0,      // No compression
            self::LOW => 0.8,       // 20% compression
            self::MEDIUM => 0.6,    // 40% compression
            self::HIGH => 0.4,      // 60% compression
            self::MAXIMUM => 0.3    // 70% compression
        };
    }

    /**
     * Get CPU cost relative to no compression
     */
    public function getCpuCostMultiplier(): float
    {
        return match ($this) {
            self::NONE => 1.0,
            self::LOW => 1.2,
            self::MEDIUM => 1.5,
            self::HIGH => 2.0,
            self::MAXIMUM => 3.0
        };
    }

    /**
     * Get minimum data size threshold for this compression level
     */
    public function getMinimumDataSize(): int
    {
        return match ($this) {
            self::NONE => 0,
            self::LOW => 1024,      // 1KB
            self::MEDIUM => 512,    // 512 bytes
            self::HIGH => 256,      // 256 bytes
            self::MAXIMUM => 128    // 128 bytes
        };
    }

    /**
     * Check if compression is beneficial for given data size
     */
    public function isBeneficialFor(int $dataSize): bool
    {
        return $this !== self::NONE && $dataSize >= $this->getMinimumDataSize();
    }

    /**
     * Get description of this compression level
     */
    public function getDescription(): string
    {
        return match ($this) {
            self::NONE => 'No compression applied',
            self::LOW => 'Fast compression with minimal CPU overhead',
            self::MEDIUM => 'Balanced compression with moderate CPU usage',
            self::HIGH => 'Good compression with higher CPU cost',
            self::MAXIMUM => 'Maximum compression with highest CPU cost'
        };
    }

    /**
     * Suggest compression level based on data size and memory pressure
     */
    public static function suggest(int $dataSize, float $memoryPressure): self
    {
        if ($dataSize < 128) {
            return self::NONE; // Too small to compress effectively
        }

        return match (true) {
            $memoryPressure >= 0.95 => self::MAXIMUM,
            $memoryPressure >= 0.85 => self::HIGH,
            $memoryPressure >= 0.75 => self::MEDIUM,
            $memoryPressure >= 0.50 => self::LOW,
            default => self::NONE
        };
    }
}
