<?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 Shopware\Plugins\ViisonCommon\Components\SubApplicationLoading\SubApplicationCodeGenerator\SubApplicationCodeGenerator;

/**
 * Class that represents a SubApplication.
 *
 * A SubApplication can have extensions, dependencies and own code.
 */
class SubApplication
{
    /**
     * @var string Name of this SubApplication
     */
    protected $name;

    /**
     * @var array Names of all SubApplications that are dependencies of this SubApplication. This is an associative
     * array with the  sub app names as keys and `true` as value to improve look up performance.
     */
    private $dependencyNames = [];

    /**
     * @var array Names of all SubApplications that extend this SubApplication. This is an associative array with the
     * sub app names as keys and `true` as value to improve look up performance.
     */
    private $extensionNames = [];

    /**
     * @var SubApplicationCodeGenerator The SubApplicationCodeGenerator to generate the code for this SubApplication
     */
    private $subApplicationCodeGenerator;

    /**
     * @param string $name
     * @param SubApplicationCodeGenerator $subApplicationCodeGenerator
     */
    public function __construct($name, SubApplicationCodeGenerator $subApplicationCodeGenerator)
    {
        $this->name = $name;
        $this->subApplicationCodeGenerator = $subApplicationCodeGenerator;
    }

    /**
     * @return string The code of this SubApplication
     */
    final public function getCode()
    {
        return $this->subApplicationCodeGenerator->generateSubApplicationCode();
    }

    /**
     * @return string The name of this SubApplication
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @return string[] Name of all SubApplications this SubApplication depends on
     */
    public function getDependencyNames()
    {
        return array_keys($this->dependencyNames);
    }

    /**
     * @return string[] Name of all SubApplications that extend this SubApplication
     */
    public function getExtensionNames()
    {
        return array_keys($this->extensionNames);
    }

    /**
     * Adds a dependency to this SubApplication
     *
     * @param string $dependencyName Name of the dependency
     */
    public function addDependencyName($dependencyName)
    {
        $this->dependencyNames[$dependencyName] = true;
    }

    /**
     * Adds dependencies to this SubApplication
     *
     * @param string[] $dependencyNames Name of the dependencies
     */
    public function addDependencyNames(array $dependencyNames)
    {
        foreach ($dependencyNames as $dependencyName) {
            $this->addDependencyName($dependencyName);
        }
    }

    /**
     * Adds an extension to this SubApplication
     *
     * @param string $extensionName Name of the extension
     */
    public function addExtensionName($extensionName)
    {
        $this->extensionNames[$extensionName] = true;
    }

    /**
     * Adds extensions to this SubApplication
     *
     * @param string[] $extensionNames Name of the extensions
     */
    public function addExtensionNames(array $extensionNames)
    {
        foreach ($extensionNames as $extensionName) {
            $this->addExtensionName($extensionName);
        }
    }

    /**
     * Removes an extension from this SubApplication.
     *
     * @param string $extensionName Name of the extension
     */
    public function removeExtensionName($extensionName)
    {
        unset($this->extensionNames[$extensionName]);
    }

    /**
     * Removes a dependency from this SubApplication.
     *
     * @param string $dependencyName Name of the dependency
     */
    public function removeDependencyName($dependencyName)
    {
        unset($this->dependencyNames[$dependencyName]);
    }
}
