<?php

/*
 * This file is part of the Serenity package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Serenity\CoreBundle\Shared\Mercure\Security\EventListener;

use Serenity\CoreBundle\Shared\Mercure\Security\CookieGenerator;
use Serenity\CoreBundle\Shared\Mercure\Security\JWTSubscriberProvider;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;

#[AsEventListener(event: KernelEvents::RESPONSE, method: 'response')]
#[AsEventListener(event: KernelEvents::REQUEST, method: 'request', priority: 50)]
readonly class CreateAuthorizationMercureRequestListener
{
    public function __construct(
        private CookieGenerator $cookieGenerator,
        private JWTSubscriberProvider $JWTSubscriberProvider,
        /** @var bool $mercureAuthorizationCookie */
        #[Autowire(env: 'MERCURE_AUTHORIZATION_COOKIE')]
        private bool $mercureAuthorizationCookie,
    ) {
    }

    /**
     * @throws \Exception
     */
    public function response(ResponseEvent $event): void
    {
        $response = $event->getResponse();
        $request = $event->getRequest();
        if (HttpKernelInterface::MAIN_REQUEST !== $event->getRequestType()
          || !\in_array('text/html', $request->getAcceptableContentTypes(), true)
        ) {
            return;
        }
        if (!$this->mercureAuthorizationCookie) {
            return;
        }
        $response->headers->removeCookie('mercureAuthorization');
        $response->headers->setCookie($this->cookieGenerator->generate());
    }

    public function request(RequestEvent $event): void
    {
        $request = $event->getRequest();
        if (HttpKernelInterface::MAIN_REQUEST !== $event->getRequestType()
          || !\in_array('text/html', $request->getAcceptableContentTypes(), true)
        ) {
            return;
        }
        if ($this->mercureAuthorizationCookie) {
            return;
        }
        $event->getRequest()->headers->set('x-mer', $this->JWTSubscriberProvider->getJwt());
    }
}
