<?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\CmsBundle\EventListener;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

/**
 * Forces the wishlist sync endpoints' responses to a clean
 * `private, no-store, must-revalidate` — the final word, after any app-level
 * FOS HttpCache `cache_control` rule has run.
 *
 * The controller already stamps the response private, but FOS's
 * `CacheControlListener` (and Contao's frontend cache machinery) can re-add
 * `public, s-maxage=…` on top afterwards. A `public, s-maxage=1y` survivor is
 * dangerous here: Varnish's builtin VCL keys on s-maxage and ignores
 * `no-store`, so the per-user bootstrap (`{authenticated: …}`) could be cached
 * and served to the wrong user. Stripping it bundle-side means the feature is
 * cache-safe in any consuming app without each app having to add a carve-out
 * rule.
 *
 * Runs at a very low priority so it executes after FOS's listener (priority 10)
 * and Contao's private-response downgrade (-1012).
 */
final class WishlistResponseCacheListener
{
    private const ROUTES = ['cms_wishlist_state', 'cms_wishlist_sync'];

    #[AsEventListener(priority: -2048)]
    public function __invoke(ResponseEvent $event): void
    {
        if (!$event->isMainRequest()) {
            return;
        }

        if (!\in_array((string) $event->getRequest()->attributes->get('_route'), self::ROUTES, true)) {
            return;
        }

        $response = $event->getResponse();

        // `no-store` + `private` is all Varnish needs — its VCL marks any such
        // response uncacheable and returns immediately, so no `Vary` is needed
        // (Vary only matters for responses that actually get stored).
        $response->headers->removeCacheControlDirective('public');
        $response->headers->removeCacheControlDirective('s-maxage');
        $response->setPrivate();
        $response->headers->addCacheControlDirective('no-store');
        $response->headers->addCacheControlDirective('must-revalidate');
        $response->setMaxAge(0);
    }
}
