<?php

namespace App\EventListener;

use Twig\Environment;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ExceptionSubscriber implements EventSubscriberInterface
{
	private $user;
	private $twig;
	private $container;

	public function __construct(Environment $twig, ContainerInterface $container, UserInterface $user = null)
	{
		$this->user = $user;
		$this->twig = $twig;
		$this->container = $container;
	}

	public static function getSubscribedEvents()
	{
		return [
			KernelEvents::EXCEPTION => [
				['onKernelException', 10]
			]
		];
	}

	public function onKernelException(ExceptionEvent $event)
	{
		// We only need to suppress errors in production environment
		if ($this->container->get('kernel')->getEnvironment() != 'prod') {
			return;
		}

		// @TODO: We need to take into account the response type as well (html, xml, json)
		$exception = method_exists($event, 'getThrowable') ? $event->getThrowable() : $event->getException();

		if ($exception->getCode() == 403) {
			// On forbidden exception, we need to either:
			// 		a) If user session is set, display forbidden page
			// 		b) If user session is not set, redirect to login page

			if (!empty($this->container->get('security.token_storage')->getToken()->getUser()) && $this->container->get('security.token_storage')->getToken()->getUser() != "anon.") {
				$template = $this->twig->render('errors/error.html.twig', [
					'code'        => 403,
					'message'     => 'Access Forbidden',
					'description' => 'You are not authorized to access this page.',
				]);
	
				$event->setResponse(new Response($template, 403));
			}
		} else {
			if ($exception instanceof NotFoundHttpException || $exception->getCode() == 404) {
				$template = $this->twig->render('errors/error.html.twig', [
					'code'        => 404,
					'message'     => 'Page not Found',
					'description' => 'We were not able to find the page you are looking for.',
				]);
	
				$event->setResponse(new Response($template, 404));
			} else {
				$template = $this->twig->render('errors/error.html.twig', [
					'message'     => 'Internal Server Error',
					'code'        => 500,
					'description' => 'Something has gone wrong on the server. Please try again later.',
				]);
	
				$event->setResponse(new Response($template, 500));
			}
		}
	}
}
