<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonCommon\Components;

use Enlight_Class;
use Enlight_Controller_Request_RequestHttp;
use Enlight_Controller_Response_ResponseHttp;
use Shopware\Components\DependencyInjection\Container;
use Shopware\Components\DependencyInjection\ContainerAwareInterface;

class ControllerFactoryService
{
    /**
     * @var Container
     */
    private $container;

    /**
     * @param Container $container the Shopware container to be passed to newly instantiated constructors
     */
    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    /**
     * Returns a controller singleton identified by its given class name, which is instantiated and configured (if
     * necessary) analogously to \Enlight_Controller_Dispatcher_Default::dispatch().
     *
     * @param string $controllerClassName the name of the class of the controller to be instantiated (the class must
     *     extend \Enlight_Controller_Action)
     * @param Enlight_Controller_Request_RequestHttp $request the request to be passed to the new controller
     * @param Enlight_Controller_Response_ResponseHttp $response the response to be passed to the new controller
     * @return \Enlight_Controller_Action the instantiated controller (may be a proxy instance)
     */
    public function getController(
        $controllerClassName,
        Enlight_Controller_Request_RequestHttp $request,
        Enlight_Controller_Response_ResponseHttp $response
    ) {
        // In all things related to instantiation of a controller, this should be implemented as analogously as possible
        // to \Enlight_Controller_Dispatcher_Default::dispatch().

        // Note: The two given arguments for the controller's constructor will be ignored in Shopware >= v5.6.0-RC1.
        // Controller constructor arguments no longer accept arguments, see \Enlight_Controller_Action.
        /** @var \Enlight_Controller_Action $controller */
        $controller = Enlight_Class::Instance($controllerClassName, [$request, $response]);

        if (method_exists($controller, 'initController')) {
            // Shopware >= v5.6.0-RC1
            // In Shopware 5.6, the \Enlight_Controller_Action controller base class no longer takes constructor
            // arguments, and requires to instead supply request and response via the initController method.
            $controller->initController($request, $response);
        }

        // Set explicit 'front' service (\Enlight_Controller_Front, available as $this->Front() in a controller).
        // \Enlight_Controller_Dispatcher_Default::dispatch sets it explicitly as well.
        // If left unset, \Enlight_Controller_Action::Front() a controller's 'front' to the Shopware global's
        // container's front service.
        $controller->setFront($this->container->get('front'));

        if ($controller instanceof ContainerAwareInterface) {
            $controller->setContainer($this->container);
        }

        return $controller;
    }
}
