<?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\Classes\Subscribers;

/**
 * @deprecated Use Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\AbstractSubApplicationRegistrationSubscriber instead!
 */
// phpcs:ignore VIISON.Classes.AbstractClassName
abstract class SubApplicationRegistration extends AbstractBaseSubscriber
{
    /**
     * If this property is set to 'true', all sub applications returned by 'getSubApplications()' will be rendered
     * without using Smarty. Setting this field has the same effect as setting the fifth parameter of every application
     * signature to 'true'. Please note that once this property is set to 'true', it is not possible anymore to render
     * any sub application that is registered by this subscriber using Smarty!
     *
     * @var boolean
     */
    protected $disableSmartyRenderingForAllApps = false;

    /**
     * Returns an associative array of sub application names and the names of extended backend
     * applications. That is, the key is the name of the custom sub application, while the value
     * is either the name of the extended backend application, or an array containing the name
     * of the extended backend application as the first element and an array of names of other
     * backend applications the custom application depends on as the second element. A simple
     * implementation of this method could look like the following:
     *
     *  return array(
     *      'MyCoolSubApplicationLoadedWithIndex' => 'Index'
     *      'MyCoolExtensionOfTheOrderSubApplicationWithExtraDependencies' => array(
     *          'Order',
     *          array(
     *              'Article',
     *              'Mail'
     *          )
     *      )
     *  );
     *
     * If inheritance is used within the sub app, parent classes have to be defined before their
     * child classes. For this reason, files containing base classes can be prioritized to be
     * output before the other JavaScript code. These prioritized files can be given in an array
     * as the third argument. Files given here are output in the given order in front of the other
     * JavaScript code of this sub app. E.g. if 'model/base.js' and 'store/base.js' contain base
     * classes, the implementation may look as follows:
     *
     *  return array(
     *      'MyCoolExtensionOfTheOrderSubApplicationWithExtraDependencies' => array(
     *          'Order',
     *          array(
     *              'Article',
     *              'Mail'
     *          ),
     *          array(
     *              'model/base.js',
     *              'store/base.js',
     *          )
     *      )
     *  );
     *
     * If you would like to register a sub application, which uses a controller in a customer
     * namespace (e.g. if that sub application is just meant as a dependable component for other
     * applications), you can provide the namespaced class name as the optional fourth parameter:
     *
     *  return array(
     *      'MyCoolExtensionMeantAsADependency' => array(
     *          null,
     *          array(),
     *          array(),
     *          '\My\Customer\Namespace\Of\The\Controller\Class'
     *      )
     *  );
     *
     * It is possible to disable Smarty rendering for a sub application. If you do so, the app's code is just
     * concatenated and added to the response without any transformations. View parameters and snippets are made
     * available via JavaScript helpers. To disable Smarty rendering, you can set the optional fifth parameter to true:
     *
     *  return array(
     *      'MyCoolSmartylessApp' => array(
     *          null,
     *          array(),
     *          array(),
     *          null,
     *          true
     *      )
     *  );
     *
     * @return array
     */
    abstract public function getSubApplications();

    /**
     * @see \Shopware\Plugins\ViisonCommon\Classes\Subscribers\Base::getSubscribedEvents()
     */
    public static function getSubscribedEvents()
    {
        return [
            'ViisonCommon_SubApplicationRegistration' => 'onSubApplicationRegistration',
        ];
    }

    /**
     * Registers all sub applications that are returned by self::getSubApplications()
     * with the JS loader.
     *
     * @param \Enlight_Event_EventArgs $args
     * @throws \Exception If a sub application registration has an invalid format.
     */
    public function onSubApplicationRegistration(\Enlight_Event_EventArgs $args)
    {
        foreach ($this->getSubApplications() as $extensionName => $subApplication) {
            // Parse sub application name and dependencies
            $subApplicationName = $subApplication;
            $dependencies = [];
            $controllerClass = null;
            $disableSmartyRendering = false;
            if (is_array($subApplication) && count($subApplication) >= 1) {
                // Use first element as name
                $subApplicationName = $subApplication[0];
                if (count($subApplication) >= 2 && is_array($subApplication[1])) {
                    // Use second element as dependencies
                    $dependencies = $subApplication[1];
                }
                // Skip the deprecated 'prioritizedFiles' element at index 2
                if (count($subApplication) >= 4 && is_string($subApplication[3])) {
                    $controllerClass = $subApplication[3];
                }
                if (count($subApplication) >= 5 && is_bool($subApplication[4])) {
                    $disableSmartyRendering = $subApplication[4];
                }
            } elseif ($subApplication !== null && !is_string($subApplication)) {
                throw new \Exception(
                    sprintf('The value of registered sub application "%s" must either be NULL, a string or an array containing a string as the first element and arrays as the optional second and third arguments.', $extensionName)
                );
            }

            $this->get('ViisonCommonJSLoader')->registerSubApplication(
                $extensionName,
                $this->getPluginPath(),
                $dependencies,
                $subApplicationName,
                [],
                $controllerClass,
                ($this->disableSmartyRenderingForAllApps || $disableSmartyRendering)
            );
        }
    }
}
