<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\EventListener\HttpCache;

use FOS\HttpCacheBundle\CacheManager;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;

/**
 * Flush queued Varnish invalidations after each worker-handled message.
 *
 * FOS's own InvalidationListener flushes the CacheManager only on kernel/console
 * TERMINATE. A `messenger:consume` worker is a single long-running console
 * command, so without this any invalidation queued while handling a message —
 * whether a handler calls invalidate*() directly, or the CacheInvalidationListener
 * fires on the worker's ORM writes (e.g. lotting setting an attendance's stash) —
 * would sit unsent until the worker process stops. The CacheManager isn't
 * `kernel.reset`-tagged, so messenger neither drops nor flushes its queue between
 * messages; we flush it here, once per message.
 *
 * In an HTTP request these same invalidations flush at kernel.terminate, and a
 * one-shot CLI command flushes at console.terminate — this listener only covers
 * the long-running worker that neither of those reaches per-message.
 *
 * Flushing on failure too is intentional: over-invalidation (purging cache for a
 * change that ultimately rolled back) only costs a re-render, whereas a missed
 * purge leaves stale cache for the full s-maxage.
 */
#[AsEventListener(event: WorkerMessageHandledEvent::class)]
#[AsEventListener(event: WorkerMessageFailedEvent::class)]
final class FlushCacheManagerOnWorkerMessageListener
{
    public function __construct(private readonly CacheManager $cacheManager)
    {
    }

    public function __invoke(): void
    {
        $this->cacheManager->flush();
    }
}
