<?php

namespace _JchOptimizeVendor\V91\Laminas\EventManager;

use _JchOptimizeVendor\V91\Psr\Container\ContainerInterface;

use function is_string;
use function method_exists;

/**
 * Lazy listener instance.
 *
 * Used to allow lazy creation of listeners via a dependency injection
 * container.
 *
 * Lazy listener definitions have the following members:
 *
 * - listener: the service name of the listener to use.
 * - method: the method name of the listener to invoke for the specified event.
 *
 * If desired, you can pass $env at instantiation; this will be passed to the
 * container's `build()` method, if it has one, when creating the listener
 * instance.
 *
 * Pass instances directly to the event manager's `attach()` method as the
 * listener argument.
 */
class LazyListener
{
    /** @var ContainerInterface Container from which to pull listener. */
    private $container;
    /** @var array Variables/options to use during service creation, if any. */
    private $env;
    /** @var callable Marshaled listener callback. */
    private $listener;
    /** @var string Method name to invoke on listener. */
    private $method;
    /** @var string Service name of listener. */
    private $service;
    /**
     * @param array $definition
     * @param array $env
     */
    public function __construct(array $definition, ContainerInterface $container, array $env = [])
    {
        if (!isset($definition['listener']) || !is_string($definition['listener']) || empty($definition['listener'])) {
            throw new Exception\InvalidArgumentException('Lazy listener definition is missing a valid "listener" member; cannot create LazyListener');
        }
        if (!isset($definition['method']) || !is_string($definition['method']) || empty($definition['method'])) {
            throw new Exception\InvalidArgumentException('Lazy listener definition is missing a valid "method" member; cannot create LazyListener');
        }
        $this->service = $definition['listener'];
        $this->method = $definition['method'];
        $this->container = $container;
        $this->env = $env;
    }
    /**
     * Use the listener as an invokable, allowing direct attachment to an event manager.
     *
     * @return callable
     */
    public function __invoke(EventInterface $event)
    {
        $listener = $this->fetchListener();
        $method = $this->method;
        return $listener->{$method}($event);
    }
    /**
     * @return callable
     */
    private function fetchListener()
    {
        if ($this->listener) {
            return $this->listener;
        }
        // In the future, typehint against Laminas\ServiceManager\ServiceLocatorInterface,
        // which defines this message starting in v3.
        if (method_exists($this->container, 'build') && !empty($this->env)) {
            $this->listener = $this->container->build($this->service, $this->env);
            return $this->listener;
        }
        $this->listener = $this->container->get($this->service);
        return $this->listener;
    }
}
