<?php

declare(strict_types=1);

final class MyronPublicRenderProfiler
{
    /**
     * @var list<array{label:string,time:float,memory:int}>
     */
    private array $marks = [];

    public function __construct(
        private readonly bool $enabled,
    ) {
        if ($this->enabled) {
            $this->mark('start');
            register_shutdown_function([$this, 'flush']);
        }
    }

    public function mark(string $label): void
    {
        if (!$this->enabled) {
            return;
        }

        $this->marks[] = [
            'label' => preg_replace('/[^A-Za-z0-9_.:-]+/', '_', trim($label)) ?: 'mark',
            'time' => microtime(true),
            'memory' => memory_get_usage(true),
        ];
    }

    public function flush(): void
    {
        if (!$this->enabled || $this->marks === []) {
            return;
        }

        $first = $this->marks[0]['time'];
        $previous = $first;
        $segments = [];
        foreach ($this->marks as $mark) {
            $elapsedMs = round(($mark['time'] - $first) * 1000, 2);
            $deltaMs = round(($mark['time'] - $previous) * 1000, 2);
            $segments[] = $mark['label'] . '=' . $elapsedMs . 'ms(+' . $deltaMs . 'ms,' . $mark['memory'] . 'b)';
            $previous = $mark['time'];
        }

        error_log('[myron-public-render] ' . implode(' ', $segments));
    }
}

function myronPublicRenderProfiler(): MyronPublicRenderProfiler
{
    static $profiler = null;

    if ($profiler instanceof MyronPublicRenderProfiler) {
        return $profiler;
    }

    $enabled = filter_var((string) (getenv('MYRON_PUBLIC_RENDER_PROFILING') ?: ''), FILTER_VALIDATE_BOOL);
    $profiler = new MyronPublicRenderProfiler((bool) $enabled);

    return $profiler;
}
