<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Queue;

use PpPhp\Core\Platform\Event\Queue\Contracts\QueueDriverInterface;
use PpPhp\Core\Platform\Event\Queue\Contracts\QueueInterface;

final class DeferredEventQueue implements QueueInterface
{
    public function __construct(private readonly QueueDriverInterface $driver) {}

    public function enqueue(DeferredEvent $event): string { return $this->driver->push($event); }
    public function dequeue(): ?DeferredEvent { return $this->driver->pop(); }
    public function peek(): ?DeferredEvent { return $this->driver->peek(); }
    public function cancel(string $id): bool { return $this->driver->cancel($id); }
    public function clear(): void { $this->driver->clear(); }

    public function flush(callable $handler): int
    {
        $count = 0;
        while (($event = $this->dequeue()) !== null) {
            $handler($event);
            $count++;
        }
        return $count;
    }

    public function contains(string $id): bool
    {
        foreach ($this->driver->all() as $event) {
            if ($event->id() === $id) {
                return true;
            }
        }
        return false;
    }

    public function size(): int { return $this->driver->size(); }
    public function isEmpty(): bool { return $this->size() === 0; }

    public function snapshot(): QueueSnapshot
    {
        return new QueueSnapshot($this->driver->name(), array_map(static fn (DeferredEvent $event): array => $event->toArray(), $this->driver->all()));
    }

    public function restore(QueueSnapshot $snapshot): void { $this->driver->restore($snapshot); }
    public function statistics(): QueueStatistics { return $this->driver->statistics(); }
}
