<?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\Subscriber;

// Require the ViisonCommonGridLabelPrinting controller here once, since it is loaded
// by the ViisonCommonJSLoader, but the class is not included. Hence, to be able to inherit
// From the ViisonCommonGridLabelPrinting controller, we must add require it before.
require_once(__DIR__ . '/../Controllers/Backend/ViisonCommonGridLabelPrinting.php');

use Doctrine\Common\Collections\ArrayCollection;
use Enlight\Event\SubscriberInterface;
use Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\JsLoaderService;
use Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\SubApplicationRegistry;
use Shopware\Plugins\ViisonCommon\Components\ViisonCommonCompatibilityCheck;

/**
 * DO NOT USE THIS CLASS!
 *
 * @deprecated This class exists for backwards compatibility only, use Shopware\Plugins\ViisonCommon\Subscribers\Common instead.
 */
class Common implements SubscriberInterface
{
    /**
     * The name of the event, which is fired when starting to collect sub applications for the JS loader.
     */
    const EVENT_COLLECT_INDEX_POPUP_WINDOWS = 'Shopware_Plugins_ViisonCommon_CollectIndexPopupWindows';

    /**
     * @var string $path
     */
    private $path;

    /**
     * @var array $indexPopupWindowSubAppQueue
     */
    private $indexPopupWindowSubAppQueue;

    /**
     * Common constructor.
     *
     * @param string $path
     */
    public function __construct($path)
    {
        $this->path = $path;
        $this->indexPopupWindowSubAppQueue = [];
    }

    public static function getSubscribedEvents()
    {
        return [
            'Enlight_Bootstrap_InitResource_ViisonCommonCompatibilityCheck' => 'onInitResourceViisonCommonCompatibilityCheck',
            'Enlight_Plugins_ViewRenderer_FilterRender' => 'onViewRendererFilterRender',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonCompatibilityCheck' => 'onGetControllerPathBackendViisonCommonCompatibilityCheck',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonConfigDocument' => 'onGetControllerPathBackendViisonCommonConfigDocument',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonCurrencyFormatter' => 'onGetControllerPathBackendViisonCommonCurrencyFormatter',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonStatusTranslator' => 'onGetControllerPathBackendViisonCommonStatusTranslator',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonHintPanel' => 'onGetControllerPathBackendViisonCommonHintPanel',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonGridLabelPrinting' => 'onGetControllerPathBackendViisonCommonGridLabelPrinting',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonIndexPopup' => 'onGetControllerPathBackendViisonCommonIndexPopup',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonMailComposer' => 'onGetControllerPathBackendViisonCommonMailComposer',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonMigration' => 'onGetControllerPathBackendViisonCommonMigration',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonShopwareVersion' => 'onGetControllerPathBackendViisonCommonShopwareVersion',
            'Enlight_Controller_Dispatcher_ControllerPath_Backend_ViisonCommonAnalytics' => 'onGetControllerPathBackendViisonCommonAnalytics',
            'ViisonCommon_SubApplicationRegistration' => [
                'onSubApplicationRegistration',
                -1000,
            ],
            JsLoaderService::EVENT_NOTIFY_FINISH_SUB_APPLICATION_REGISTRATION => 'onViisonCommonJSLoaderFinishSubApplicationRegistration',
            JsLoaderService::EVENT_NOTIFY_UNTIL_REGISTER_SUB_APPLICATION => 'onRegisterSubApplication',
            'Enlight_Controller_Action_PostDispatch_Backend_Index' => 'onPostDispatchBackend',
        ];
    }

    /**
     * Exposes the ViisonCommonCompatibilityCheck controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonCompatibilityCheck(\Enlight_Event_EventArgs $args)
    {
        return $this->path . '/Controllers/Backend/ViisonCommonCompatibilityCheck.php';
    }

    /**
     * Exposes the ViisonCommonConfigDocument controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonConfigDocument(\Enlight_Event_EventArgs $args)
    {
        return $this->path . '/Controllers/Backend/ViisonCommonConfigDocument.php';
    }

    /**
     * Exposes the ViisonCommonCurrencyFormatter controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonCurrencyFormatter(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir(
            $this->path . 'Views/'
        );

        return $this->path . '/Controllers/Backend/ViisonCommonCurrencyFormatter.php';
    }

    /**
     * Exposes the ViisonCommonStatusTranslator controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonStatusTranslator(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir($this->path . 'Views/');

        return $this->path . '/Controllers/Backend/ViisonCommonStatusTranslator.php';
    }

    /**
     * Exposes the ViisonCommonHintPanel controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonHintPanel(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir(
            $this->path . 'Views/'
        );

        return $this->path . '/Controllers/Backend/ViisonCommonHintPanel.php';
    }

    /**
     * Exposes the ViisonCommonGridLabelPrinting controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonGridLabelPrinting(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir(
            $this->path . 'Views/'
        );

        return $this->path . '/Controllers/Backend/ViisonCommonGridLabelPrinting.php';
    }

    /**
     * Exposes the ViisonCommonIndexPopup controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonIndexPopup(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir(
            $this->path . 'Views/'
        );

        return $this->path . '/Controllers/Backend/ViisonCommonIndexPopup.php';
    }

    /**
     * Exposes the ViisonCommonMailComposer controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonMailComposer(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir(
            $this->path . 'Views/'
        );

        return $this->path . '/Controllers/Backend/ViisonCommonMailComposer.php';
    }

    /**
     * Exposes the ViisonCommonMigrations controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonMigration(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir(
            $this->path . 'Views/'
        );

        return $this->path . '/Controllers/Backend/ViisonCommonMigration.php';
    }

    /**
     * Exposes the ViisonCommonShopwareVersion controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonShopwareVersion(\Enlight_Event_EventArgs $args)
    {
        return $this->path . '/Controllers/Backend/ViisonCommonShopwareVersion.php';
    }

    /**
     * Exposes the ViisonCommonVariantComboBox controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonVariantComboBox(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir(
            $this->path . 'Views/'
        );

        return $this->path . '/Controllers/Backend/ViisonCommonVariantComboBox.php';
    }

    /**
     * Exposes the ViisonCommonVariantComboBox controller.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return string The path of the controller.
     */
    public function onGetControllerPathBackendViisonCommonAnalytics(\Enlight_Event_EventArgs $args)
    {
        Shopware()->Template()->addTemplateDir(
            $this->path . 'Views/'
        );

        return $this->path . '/Controllers/Backend/ViisonCommonAnalytics.php';
    }

    public function onInitResourceViisonCommonCompatibilityCheck()
    {
        return new ViisonCommonCompatibilityCheck();
    }

    public function onViewRendererFilterRender(\Enlight_Event_EventArgs $args)
    {
        $renderedJsCode = $args->getReturn();

        Shopware()->Snippets()->addConfigDir($this->path . '/snippets/');

        /**
         * We have to filter out the initial backend index request, which is a (lower case) 'index' request with no
         * file parameter. (Also see Shopwares Shopware_Controllers_Backend_Index::indexAction
         * https://github.com/shopware/shopware/blob/7f02cd0dcadec57d4db1eafad6093c3d1a11d61c/engine/Shopware/Controllers/Backend/Index.php#L95-L98 )
         * Load our JS extensions only if this is an actual index script request.
         */
        $request = $args->getSubject()->Action()->Request();
        $isIndexRequest = $request->getActionName() === 'index';
        $isScriptRequest = $request->getParam('file') !== null;

        if ($isScriptRequest && $isIndexRequest) {
            $controllerName = $request->getControllerName();

            $renderedJsCode = Shopware()->Container()->get('viison_common.js_loader')->extendSubAppRequest(
                $controllerName,
                $renderedJsCode
            );

            // In case this is a request for the "base" models, prepend our ViisonCommonApp, the ClassManager and
            // Class preprocessors in the very beginning of the code and append the override of the Shopware class
            // loader.
            if ($controllerName === 'base') {
                $viisonCommonApp = file_get_contents(__DIR__ . '/../Views/backend/viison_common/base.js');
                $loaderOverrideCode = file_get_contents(__DIR__ . '/../Views/backend/viison_common/base/loader.js');
                $renderedJsCode = $viisonCommonApp . $renderedJsCode . $loaderOverrideCode;
            }
        }

        return $renderedJsCode;
    }

    /**
     * @param \Enlight_Event_EventArgs $args
     */
    public function onSubApplicationRegistration(\Enlight_Event_EventArgs $args)
    {
        // Ask plugins to register for the index popup window queue
        $indexPopups = Shopware()->Events()->collect(self::EVENT_COLLECT_INDEX_POPUP_WINDOWS, new ArrayCollection());
        foreach ($indexPopups as $item) {
            // Save sub app name and position
            $subApp = (is_array($item)) ? $item[0] : $item;
            if ($subApp !== null) {
                $this->indexPopupWindowSubAppQueue[$subApp] = (is_array($item) && count($item) >= 2) ? $item[1] : 0;
            }
        }
        // Sort by queue position
        asort($this->indexPopupWindowSubAppQueue);
        // Marks all the SubApplications in the queue as not registered yet
        $this->indexPopupWindowSubAppQueue = array_fill_keys(array_keys($this->indexPopupWindowSubAppQueue), false);
    }

    /**
     * Gets called for every SubApplication that is registered.
     *
     * @param \Enlight_Event_EventArgs $args
     */
    public function onRegisterSubApplication(\Enlight_Event_EventArgs $args)
    {
        // Mark the registered SubApplication in the indexPopupWindowSubAppQueue as actually registered.
        if (array_key_exists($args->get('name'), $this->indexPopupWindowSubAppQueue)) {
            // Save the registration for later
            $this->indexPopupWindowSubAppQueue[$args->get('name')] = true;
        }
    }

    /**
     * Gets called when the SubApplication registration has finished.
     *
     * @param \Enlight_Event_EventArgs $args
     */
    public function onViisonCommonJSLoaderFinishSubApplicationRegistration(\Enlight_Event_EventArgs $args)
    {
        // Remove all registered SubApplications of the indexPopupWindowSubAppQueue but the first actually registered.
        $firstLoaded = false;
        foreach ($this->indexPopupWindowSubAppQueue as $subAppName => $isRegistered) {
            if ($isRegistered === true && !$firstLoaded) {
                $firstLoaded = true;
                continue;
            }
            /** @var SubApplicationRegistry $subApplicationRegistry */
            $subApplicationRegistry = $args->get('subApplicationRegistry');
            $subApplicationRegistry->removeSubApplication($subAppName);
        }
    }

    /**
     * Includes the custom base header.
     *
     * @param \Enlight_Event_EventArgs $args The event parameters.
     */
    public function onPostDispatchBackend(\Enlight_Event_EventArgs $args)
    {
        $view = $args->getSubject()->View();
        $view->addTemplateDir($this->path . '/Views/');
        $view->extendsTemplate('backend/viison_common/header.tpl');
    }
}
