<?php 
 
namespace App\EventListener; 
 
use Psr\Log\LoggerInterface; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Component\HttpKernel\Event\RequestEvent; 
use Symfony\Component\Routing\RouterInterface; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; 
use Symfony\Contracts\Translation\TranslatorInterface; 
 
//use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; 
 
class SessionIdleListener 
{ 
 
    /** 
     * @var int 
     */ 
    private $maxIdleTime; 
    /** 
     * @var int 
     */ 
    private $maxBackendIdleTime; 
 
    /** 
     * @var Session 
     */ 
    private $session; 
 
    /** 
     * @var TokenStorageInterface 
     */ 
    private $tokenStorage; 
 
    /** 
     * @var RouterInterface 
     */ 
    private $router; 
 
    /** 
     * @var AuthorizationCheckerInterface 
     */ 
    private $checker; 
 
    /** 
     * @var LoggerInterface 
     */ 
    private $logger; 
 
    /** 
     * @var TranslatorInterface 
     */ 
    private $translator; 
 
    /** 
     * SessionIdleHandler constructor. 
     * @param Session $session 
     * @param TokenStorageInterface $tokenStorage 
     * @param RouterInterface $router 
     * @param AuthorizationCheckerInterface $checker 
     * @param LoggerInterface $logger 
     * @param TranslatorInterface $translator 
     * @param int $maxIdleTime 
     * @param int $maxBackendIdleTime 
     */ 
    public function __construct(Session $session, TokenStorageInterface $tokenStorage, RouterInterface $router, AuthorizationCheckerInterface $checker, LoggerInterface $logger, TranslatorInterface $translator, int $maxIdleTime = 300, int $maxBackendIdleTime = 1800) 
    { 
        $this->maxIdleTime = $maxIdleTime; 
        $this->maxBackendIdleTime = $maxBackendIdleTime; 
        $this->session = $session; 
        $this->router = $router; 
        $this->checker = $checker; 
        $this->tokenStorage = $tokenStorage; 
        $this->logger = $logger; 
        $this->translator = $translator; 
    } 
 
    /** 
     * @param RequestEvent $event 
     */ 
    public function onKernelRequest(RequestEvent $event): void 
    { 
//        $this->logger->error("max_idle_time: ".$this->maxIdleTime); 
//        $this->logger->error("master: ".$event->isMasterRequest()); 
//        $this->logger->error("anonymous: ".$this->isAuthenticatedAnonymously()); 
        if (!$event->isMainRequest() 
            || $this->maxIdleTime <= 0 
            || $this->isAuthenticatedAnonymously()) { 
//            $this->logger->error("return"); 
 
            return; 
        } 
 
        $admin = 0; 
        if ($this->checker->isGranted("ROLE_BACKEND_USER")) { 
            $admin = 1; 
        } 
//        $this->logger->error("admin: ". $admin); 
 
 
//        $session = $this->session; 
//        $session->start(); 
//        $this->logger->error("now: ".time() ); 
//        $this->logger->error("last used: ".$this->session->getMetadataBag()->getLastUsed()); 
//        $this->logger->error("diff  : ".((time() - $this->session->getMetadataBag()->getLastUsed()))); 
//        $this->logger->error("greater: ".((time() - $this->session->getMetadataBag()->getLastUsed()) <= $this->maxIdleTime)); 
//        $this->logger->error("greater: ".((time() - $this->session->getMetadataBag()->getLastUsed()) <= $this->maxBackendIdleTime)); 
 
        if ($admin === 0 && ((time() - $this->session->getMetadataBag()->getLastUsed()) <= $this->maxIdleTime)) { 
            return; 
        } 
        if ($admin === 1 && ((time() - $this->session->getMetadataBag()->getLastUsed()) <= $this->maxBackendIdleTime)) { 
            return; 
        } 
 
        $this->tokenStorage->setToken(); 
        $this->session->getFlashBag()->set('error', $this->translator->trans('idle_logout.exited')); 
 
        if ($admin === 1) { 
            $event->setResponse(new RedirectResponse($this->router->generate('backend_login'))); 
        } else { 
            $event->setResponse(new RedirectResponse($this->router->generate('app_login'))); 
        } 
 
    } 
 
    /** 
     * @return bool 
     */ 
    private function isAuthenticatedAnonymously(): bool 
    { 
//        $this->logger->error(serialize($this->tokenStorage->getToken())); 
//        $this->logger->error(is_a($this->tokenStorage->getToken(), AnonymousToken::class)); 
 
        return !$this->tokenStorage->getToken() 
            || 
            is_a($this->tokenStorage->getToken(), AnonymousToken::class) 
            //!$this->checker->isGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY) 
 
            ; 
    } 
 
}