<?php

declare(strict_types=1);

namespace App\Framework\Discovery\Events;

use App\Framework\Core\ValueObjects\Byte;
use App\Framework\Core\ValueObjects\Timestamp;

/**
 * Event fired when memory cleanup is performed
 */
final readonly class MemoryCleanupEvent
{
    public function __construct(
        public Byte $beforeUsage,
        public Byte $afterUsage,
        public Byte $memoryFreed,
        public int $collectedCycles,
        public bool $wasEmergency,
        public ?string $triggerReason,
        public ?string $context,
        public Timestamp $timestamp
    ) {
    }

    public function wasEffective(): bool
    {
        return $this->memoryFreed->greaterThan(Byte::zero()) || $this->collectedCycles > 0;
    }

    public function getEffectivenessRatio(): float
    {
        if ($this->beforeUsage->isEmpty()) {
            return 0.0;
        }

        return $this->memoryFreed->toBytes() / $this->beforeUsage->toBytes();
    }

    public function getCleanupType(): string
    {
        return $this->wasEmergency ? 'emergency' : 'routine';
    }

    public function toArray(): array
    {
        return [
            'before_usage' => $this->beforeUsage->toHumanReadable(),
            'before_usage_bytes' => $this->beforeUsage->toBytes(),
            'after_usage' => $this->afterUsage->toHumanReadable(),
            'after_usage_bytes' => $this->afterUsage->toBytes(),
            'memory_freed' => $this->memoryFreed->toHumanReadable(),
            'memory_freed_bytes' => $this->memoryFreed->toBytes(),
            'collected_cycles' => $this->collectedCycles,
            'was_emergency' => $this->wasEmergency,
            'trigger_reason' => $this->triggerReason,
            'context' => $this->context,
            'was_effective' => $this->wasEffective(),
            'effectiveness_ratio' => round($this->getEffectivenessRatio() * 100, 2),
            'cleanup_type' => $this->getCleanupType(),
            'timestamp' => $this->timestamp->toFloat(),
        ];
    }
}
