<?php

namespace FiloBlu\Esb\Model;

use FiloBlu\Esb\Api\Data\ObjectTypeDescriptorInterface;
use FiloBlu\Esb\Api\ObjectTypeLoaderInterface;
use RuntimeException;

/**
 * Class ObjectTypeLoaderResolver
 * @package FiloBlu\Esb\Model
 */
class ObjectTypeLoaderResolver implements ObjectTypeLoaderResolverInterface
{
    /** @var array */
    protected $loaders = [];

    /**
     * ObjectTypeLoaderResolver constructor.
     * @param array $loaders
     */
    public function __construct(array $loaders)
    {
        $this->loaders = $loaders;
    }

    /**
     * @inheritDoc
     */
    public function get($uniqueName): ObjectTypeLoaderInterface
    {

        /**
         * @var ObjectTypeLoaderInterface $loader
         */
        foreach ($this->loaders as $loader) {

            if ($loader->getUniqueName() === $uniqueName) {
                return $loader;
            }
        }

        throw new RuntimeException(__('no loader found'));
    }

    /**
     * @inheritDoc
     */
    public function has($name): bool
    {
        /** @var ObjectTypeLoaderInterface $loader */
        foreach ($this->loaders as $loader) {
            if ($loader->getUniqueName() === $name) {
                return true;
            }
        }

        return false;
    }

    /**
     * @inheritDoc
     */
    public function getAll(): array
    {
        return $this->loaders;
    }

    /**
     * @inheritDoc
     */
    public function getFor(ObjectTypeDescriptorInterface $objectTypeDescriptor): ObjectTypeLoaderInterface
    {
        $fallback = null;

        /**
         * @var ObjectTypeLoaderInterface $loader
         */
        foreach ($this->loaders as $loader) {

            if($objectTypeDescriptor->getTypeCode() === $loader->getObjectTypeDescriptor()->getTypeCode())
            {
                return $loader;
            }

            if ($loader->isSuitableFor($objectTypeDescriptor)) {
                $fallback = $loader;
            }
        }

        if($fallback!== null) {
            return  $fallback;
        }

        throw new RuntimeException(__('no loader found'));
    }
}
