<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Compiler;

use PpPhp\Core\Platform\Event\Registry\EventListenerRegistry;
use PpPhp\Core\Platform\Event\Registry\ListenerRecord;

final class ListenerRegistryCompiler
{
    public const CACHE_FILE = 'storage/cache/events/compiled-listener-registry.php';

    public function compile(EventListenerRegistry $registry, string $basePath): array
    {
        $data = [
            'generatedAt' => date('c'),
            'events' => $registry->events(),
            'listenerCount' => $registry->count(),
            'listeners' => array_map(
                static fn (ListenerRecord $record): array => $record->toArray(),
                $registry->all()
            ),
            'dispatchTable' => [],
        ];

        foreach ($registry->events() as $eventName) {
            $data['dispatchTable'][$eventName] = array_map(
                static fn (ListenerRecord $record): string => $record->id(),
                $registry->listenersFor($eventName)
            );
        }

        $file = rtrim($basePath, DIRECTORY_SEPARATOR) . '/' . self::CACHE_FILE;
        $dir = dirname($file);

        if (!is_dir($dir)) {
            mkdir($dir, 0775, true);
        }

        file_put_contents($file, "<?php\nreturn " . var_export($data, true) . ";\n");

        return $data;
    }

    public function load(string $basePath): ?CompiledListenerRegistry
    {
        $file = rtrim($basePath, DIRECTORY_SEPARATOR) . '/' . self::CACHE_FILE;

        if (!is_file($file)) {
            return null;
        }

        $data = require $file;

        return is_array($data) ? new CompiledListenerRegistry($data) : null;
    }
}
