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

use Doctrine\Common\Collections\ArrayCollection;
use Shopware\Plugins\ViisonCommon\Classes\Subscribers\AbstractBaseSubscriber;
use Shopware\Plugins\ViisonPickwareCommon\Classes\ApiRequestCompatibility\Layer;
use Shopware\Plugins\ViisonPickwareCommon\Components\ApiRequestCompatibilityManager;

class RestApiRequestCompatibilityLayerSubscriber extends AbstractBaseSubscriber
{
    /**
     * @var string $compatibilityLayerRootPath
     */
    private $compatibilityLayerRootPath;

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

    /**
     * @param \Shopware_Components_Plugin_Bootstrap $pluginBootstrap
     * @param string $compatibilityLayerRootPath
     * @param string $compatibilityLayerBaseNamespace
     */
    public function __construct(\Shopware_Components_Plugin_Bootstrap $pluginBootstrap, $compatibilityLayerRootPath = null, $compatibilityLayerBaseNamespace = null)
    {
        parent::__construct($pluginBootstrap);

        $this->compatibilityLayerRootPath = $compatibilityLayerRootPath;
        $this->compatibilityLayerBaseNamespace = $compatibilityLayerBaseNamespace;
    }

    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents()
    {
        return [
            ApiRequestCompatibilityManager::EVENT_COLLECT_API_REQUEST_COMPATIBILITY_LAYERS => 'onCollectApiRequestCompatibilityLayers',
        ];
    }

    /**
     * @param \Enlight_Event_EventArgs $args
     * @return \Doctrine\Common\Collections\ArrayCollection|null
     */
    public function onCollectApiRequestCompatibilityLayers(\Enlight_Event_EventArgs $args)
    {
        if (!$this->compatibilityLayerRootPath || !$this->compatibilityLayerBaseNamespace) {
            return null;
        }

        // Iterate all files contained in the layer directory path and parses their names to find all compatibility
        // layers, which can be applied to the requested controller with the given name and whose version is greater or
        // equal the required API version.
        $compatibilityLayers = new ArrayCollection();
        $iterator = new \DirectoryIterator($this->getPluginPath() . $this->compatibilityLayerRootPath);
        foreach ($iterator as $file) {
            if (!$file->isFile()) {
                continue;
            }

            // Parse file name and compare it to the name of the requested controller
            preg_match('/^((.*)\\d{8})\\.php/', $file->getFilename(), $matches);
            if (count($matches) !== 3 || mb_strtolower($matches[2]) !== mb_strtolower($args->get('controllerName'))) {
                continue;
            }

            // Create layer and check its version
            $fullLayerClass = $this->compatibilityLayerBaseNamespace . '\\' . $matches[1];
            /** @var Layer $layer */
            $layer = new $fullLayerClass();
            if (version_compare($args->get('requiredVersion'), $layer->getVersion(), '<=')) {
                $compatibilityLayers->add($layer);
            }
        }

        return $compatibilityLayers;
    }
}
