<?php

declare(strict_types=1);

namespace App\Framework\Logging\Processors;

use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Logging\LogProcessor;
use App\Framework\Logging\LogRecord;
use App\Framework\Performance\MemoryMonitor;

/**
 * Performance Processor für Timing-Metriken
 *
 * Fügt Performance-Daten zu jedem Log-Eintrag hinzu:
 * - Memory Usage (current, peak) via MemoryMonitor
 * - Execution Time (seit Request-Start)
 * - CPU Time (wenn verfügbar)
 */
final class PerformanceProcessor implements LogProcessor
{
    private static ?Timestamp $requestStartTime = null;
    private readonly MemoryMonitor $memoryMonitor;

    public function __construct(
        private readonly bool $includeMemory = true,
        private readonly bool $includeExecutionTime = true,
        ?MemoryMonitor $memoryMonitor = null
    ) {
        $this->memoryMonitor = $memoryMonitor ?? new MemoryMonitor();

        if (self::$requestStartTime === null) {
            self::$requestStartTime = isset($_SERVER['REQUEST_TIME_FLOAT'])
                ? Timestamp::fromFloat($_SERVER['REQUEST_TIME_FLOAT'])
                : Timestamp::now();
        }
    }

    public function process(LogRecord $record): LogRecord
    {
        $performance = [];

        if ($this->includeMemory) {
            $summary = $this->memoryMonitor->getSummary();

            $performance['memory_current'] = $summary->current->format();
            $performance['memory_current_bytes'] = $summary->current->toBytes();
            $performance['memory_peak'] = $summary->peak->format();
            $performance['memory_peak_bytes'] = $summary->peak->toBytes();
            $performance['memory_usage_percent'] = $summary->usagePercentage->format();
        }

        if ($this->includeExecutionTime) {
            $elapsed = Timestamp::now()->diffInMilliseconds(self::$requestStartTime);
            $performance['execution_time_ms'] = round($elapsed, 2);
        }
