<?php declare(strict_types=1);

namespace Newland\Toubiz\Search\Neos\Backend;

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Configuration\Exception\InvalidConfigurationException;
use Neos\Flow\ObjectManagement\Exception\InvalidObjectException;
use Neos\Flow\ObjectManagement\ObjectManager;
use Newland\Contracts\Neos\Search\SearchBackend;

/**
 * @Flow\Scope("singleton")
 */
class SearchBackendFactory
{

    /**
     * @var string|null
     * @Flow\InjectConfiguration(package="Newland.Toubiz.Search.Neos", path="backend")
     */
    protected $configuredBackend;

    /**
     * @var ObjectManager
     * @Flow\Inject()
     */
    protected $objectManager;

    public function getSearchBackendFromConfiguration(): SearchBackend
    {
        $className = $this->configuredBackend;

        if ($className === null || !\is_string($className)) {
            throw new InvalidConfigurationException('
                Please be sure to set `Newland.Toubiz.Search.Neos.backend`
                to a valid fully qualified classname
            ');
        }

        if (!class_exists($className)) {
            throw new InvalidConfigurationException(sprintf('
                Please be sure to set `Newland.Toubiz.Search.Neos.backend`
                to a valid fully qualified classname. %s does not exist.
            ', $className));
        }

        $instance = $this->objectManager->get($className);
        if (!($instance instanceof SearchBackend)) {
            throw new InvalidObjectException(sprintf(
                'The class configured in `Newland.Toubiz.Search.Neos.backend` must implement %s but %s does not.',
                SearchBackend::class,
                $className
            ));
        }

        return $instance;
    }
}
