<?php

namespace App\Service\SnipParser;

use App\Entity\Snip;
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\ServiceLocator;

readonly class ParserFactory
{
    public function __construct(
        #[AutowireLocator(ParserInterface::class, defaultIndexMethod: 'getName')]
        private ServiceLocator $locator
    ) {}

    /**
     * @template T of ParserInterface
     *
     * @param class-string<T> $id
     *
     * @return T
     * @throws ServiceNotFoundException
     */
    public function get(string $id): ParserInterface
    {
        return $this->locator->get($id);
    }

    public function getBySnip(Snip $snip): ParserInterface
    {
        $parser = $snip->parser;
        if (null === $parser) {
            throw new ServiceNotFoundException(sprintf('Unknown parser for snip "%s"', $snip->parser));
        }

        return $this->get($parser);
    }

    /**
     * @return iterable<string, ParserInterface>
     */
    public function getAll(): iterable
    {
        return $this->locator->getIterator();
    }

    public function getChoices(): iterable
    {
        foreach ($this->getAll() as $parser) yield $parser::getName();
    }
}
