<?php

namespace Webapp\Core\SQLFilter;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\Filter\SQLFilter;
use Shared\RightManagement\EventSubscriber\FilterConfigurator;
use Webapp\Core\Annotation\GraphicallyDeletable;

class GraphicallyDeletableFilter extends SQLFilter
{
    /**
     * @var FilterConfigurator
     */
    protected $listener;

    /**
     * @var EntityManagerInterface
     */
    protected $entityManager;

    /**
     * @param string $targetTableAlias
     *
     * @return string
     */
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
    {
        /** @var GraphicallyDeletable $classAnnotation */
        $classAnnotation = $this->getListener()->getAnnotationReader()->getClassAnnotation($targetEntity->getReflectionClass(), 'Webapp\\Core\\Annotation\\GraphicallyDeletable');
        if (null === $classAnnotation || !isset($classAnnotation->graphicallyDeletableField) ) {
            return '';
        }

        $conn = $this->getEntityManager()->getConnection();
        $platform = $conn->getDatabasePlatform();
        $column = $targetEntity->getColumnName($classAnnotation->graphicallyDeletableField);

        $addCondSql = $platform->getIsNullExpression($targetTableAlias.'.'.$column);

        return $addCondSql;
    }

    /**
     * @return FilterConfigurator
     *
     * @throws \RuntimeException
     */
    protected function getListener()
    {
        if (null === $this->listener) {
            $em = $this->getEntityManager();
            $evm = $em->getEventManager();

            foreach ($evm->getListeners() as $listeners) {
                foreach ($listeners as $listener) {
                    if ($listener instanceof FilterConfigurator) {
                        $this->listener = $listener;

                        break 2;
                    }
                }
            }

            if (null === $this->listener) {
                throw new \RuntimeException('Listener "GraphicallyDeletableFilterConfigurator" was not added to the EventManager!');
            }
        }

        return $this->listener;
    }

    /**
     * @return EntityManagerInterface
     */
    protected function getEntityManager()
    {
        if (null === $this->entityManager) {
            $refl = new \ReflectionProperty('Doctrine\ORM\Query\Filter\SQLFilter', 'em');
            $refl->setAccessible(true);
            $this->entityManager = $refl->getValue($this);
        }

        return $this->entityManager;
    }
}
