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

use Doctrine\Common\Collections\ArrayCollection;
use Shopware\Plugins\ViisonCommon\Classes\Subscribers\AbstractBaseSubscriber;
use Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\SubApplicationBuilder\ModelExtensionBuilder;
use Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\SubApplicationBuilder\StandaloneSubApplicationBuilder;
use Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\SubApplicationBuilder\SubApplicationBuilder;
use Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\SubApplicationBuilder\SubApplicationExtensionBuilder;

/**
 * Abstract Subscriber class for the registration of SubApplication with the SubApplicationJSLoaderService.
 *
 * To register `SubApplications` for your plugin implement `AbstractSubApplicationRegistrationSubscriber` class and its
 * method `createSubApplications()`. This method should call addSubApplication() to add a new `SubApplication`. The
 * return value of `addSubApplication()` is a `SubApplication` that provides a fluent API to configure your
 * `SubApplication`.
 *
 * **Example:**
 * ```php
 * <?php
 * namespace Shopware\Plugins\ViisonCommon\Subscribers;
 *
 * use Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\AbstractSubApplicationRegistrationSubscriber;
 *
 * class SubApplicationRegistrationSubscriber extends AbstractSubApplicationRegistrationSubscriber
 * {
 *     /**
 *      * @inheritdoc
 *      * /
 *     public function createSubApplications()
 *     {
 *         $this->addModelExtension('ViisonCommonBaseModelExtensions')->extendingSubApplication('Base');
 *         $this->addSubApplication('ViisonCommonCurrencyFormatter');
 *         $this->addSubApplication('ViisonCommonGridLabelPrinting');
 *         $this->addSubApplication('ViisonCommonVariantComboBox')->requiringSubApplication('ViisonCommonComboBox');
 *         $this->addSubApplicationExtension('ViisonCommonOrderActivityPerformedDate')->extendingSubApplication('Order');
 *     }
 * }
 * ```
 *
 * For more information, see the PHPDoc of {@see SubApplication} and its methods.
 */
abstract class AbstractSubApplicationRegistrationSubscriber extends AbstractBaseSubscriber
{
    /**
     * @var SubApplicationBuilder[]
     */
    private $subApplicationBuilders = [];

    /**
     * Creates the SubApplicationBuilders by using the methods $this->addSubApplication(), $this->addModelExtension() or
     * $this->addSubApplicationExtension().
     */
    abstract protected function createSubApplications();

    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents()
    {
        return [
            JsLoaderService::EVENT_COLLECT_SUB_APPLICATION_BUILDERS => 'onCollectSubApplicationBuilders',
        ];
    }

    /**
     * Method is called when the `\Shopware\Plugins\ViisonCommon\Subscribers\Common` wants us to register all
     * SubApplications to the JSLoader.
     */
    public function onCollectSubApplicationBuilders()
    {
        $this->createSubApplications();

        return new ArrayCollection($this->subApplicationBuilders);
    }

    /**
     * @param string $name The name of the SubApplication.
     * @return StandaloneSubApplicationBuilder
     */
    protected function addSubApplication($name)
    {
        $subApplicationBuilder = new StandaloneSubApplicationBuilder($name, $this->getPluginPath());
        $this->subApplicationBuilders[] = $subApplicationBuilder;

        return $subApplicationBuilder;
    }

    /**
     * @param string $name The name of the SubApplicationExtension.
     * @return SubApplicationExtensionBuilder
     */
    protected function addSubApplicationExtension($name)
    {
        $subApplicationBuilder = new SubApplicationExtensionBuilder($name, $this->getPluginPath());
        $this->subApplicationBuilders[] = $subApplicationBuilder;

        return $subApplicationBuilder;
    }

    /**
     * @param string $name The name of the ModelExtension.
     * @return ModelExtensionBuilder
     */
    public function addModelExtension($name)
    {
        $subApplicationBuilder = new ModelExtensionBuilder($name, $this->getPluginPath());
        $this->subApplicationBuilders[] = $subApplicationBuilder;

        return $subApplicationBuilder;
    }
}
