<?php

namespace NoahVet\Reef\Infrastructure\Security\Doctrine;

use Doctrine\ORM\EntityManagerInterface;
use NoahVet\Reef\Domain\Security\Port\ResourceEnumeratorInterface;
use NoahVet\Reef\Domain\Security\Port\ResourceLocatorInterface;
use Symfony\Component\Uid\Uuid;

abstract class AbstractDoctrineResourceFinder implements ResourceEnumeratorInterface, ResourceLocatorInterface
{
    /**
     * @param class-string $entityClass
     */
    public function __construct(
        protected string $entityClass,
        protected string $iamPrefix,
        protected EntityManagerInterface $entityManager,
    ) {
    }

    #[\Override]
    public function enumerate(): \Generator
    {
        $iterable = $this->entityManager->createQueryBuilder()
            ->select('a')
            ->from($this->entityClass, 'a')
            ->getQuery()->toIterable()
        ;

        foreach ($iterable as $entity) {
            yield $entity;
        }
    }

    #[\Override]
    public function findBySlug(string $slug): mixed
    {
        if (!\str_starts_with($slug, $this->iamPrefix)) {
            return null;
        }

        $id = \str_replace($this->iamPrefix, '', $slug);
        if (Uuid::isValid($id)) {
            $id = Uuid::fromString($id)->toBinary();
        }

        return $this->entityManager->createQueryBuilder()
            ->select('a')
            ->from($this->entityClass, 'a')
            ->where('a.id = :id')
            ->setParameter('id', $id)
            ->getQuery()->getOneOrNullResult()
        ;
    }
}
