<?php

namespace WordpressModels\DependencyInjection\Doctrine;



use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
use Doctrine\Bundle\DoctrineBundle\Attribute\AsMiddleware;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\IdGeneratorPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface;
use Doctrine\Bundle\DoctrineBundle\Mapping\ContainerEntityListenerResolver;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
use Doctrine\DBAL\Driver\Middleware as MiddlewareInterface;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Id\AbstractIdGenerator;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Reference;
use WordpressModels\ORM\EntityManagerFactory;

class WordpressDoctrineExtension extends Extension
{
    
    
    public function load(array $configs, ContainerBuilder $container)
    {
        $container->registerForAutoconfiguration(ServiceEntityRepositoryInterface::class)
            ->addTag(ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG);

        $container->registerForAutoconfiguration(EventSubscriberInterface::class)
            ->addTag('doctrine.event_subscriber');

        $container->registerForAutoconfiguration(AbstractIdGenerator::class)
            ->addTag(IdGeneratorPass::ID_GENERATOR_TAG);

        $container->registerAttributeForAutoconfiguration(AsEntityListener::class, static function (ChildDefinition $definition, AsEntityListener $attribute) {
            $definition->addTag('doctrine.orm.entity_listener', [
                'event'          => $attribute->event,
                'method'         => $attribute->method,
                'lazy'           => $attribute->lazy,
                'entity_manager' => $attribute->entityManager,
                'entity'         => $attribute->entity,
                'priority'       => $attribute->priority,
            ]);
        });
        $container->registerAttributeForAutoconfiguration(AsDoctrineListener::class, static function (ChildDefinition $definition, AsDoctrineListener $attribute) {
            $definition->addTag('doctrine.event_listener', [
                'event'      => $attribute->event,
                'priority'   => $attribute->priority,
                'connection' => $attribute->connection,
            ]);
        });

        $container->registerForAutoconfiguration(MiddlewareInterface::class)->addTag('doctrine.middleware');

        $container->registerAttributeForAutoconfiguration(AsMiddleware::class, static function (ChildDefinition $definition, AsMiddleware $attribute) {
            $priority = isset($attribute->priority) ? ['priority' => $attribute->priority] : [];

            if ($attribute->connections === []) {
                $definition->addTag('doctrine.middleware', $priority);

                return;
            }

            foreach ($attribute->connections as $connName) {
                $definition->addTag('doctrine.middleware', array_merge($priority, ['connection' => $connName]));
            }
        });


        $container->register(EntityManagerFactory::class)
            ->setPublic(true)
            ->setArguments([new Reference('service_container')]);

        $container->setParameter('doctrine.default_entity_manager', 'default');

        $container->register('doctrine.orm.entity_manager.config', Configuration::class)
            ->setPublic(true)
            ->setFactory([new Reference(EntityManagerFactory::class), 'createConfiguration'])
            ->setArguments(['default']);

        $container->register('doctrine.orm.default_entity_listener_resolver', ContainerEntityListenerResolver::class)
            ->setPublic(true)
            ->setArguments([new Reference('service_container')]);
        $container->setAlias(ContainerEntityListenerResolver::class, 'doctrine.orm.default_entity_listener_resolver');

        $container->register('doctrine.orm.default_entity_manager', EntityManagerInterface::class)
            ->setPublic(true)
            ->setFactory([new Reference(EntityManagerFactory::class), 'create'])
            ->setArguments([new Reference('doctrine.orm.entity_manager.config')])
            ->setAutowired(false);
        $container->setAlias(EntityManagerInterface::class, 'doctrine.orm.default_entity_manager');

    }

}