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

use Shopware\Plugins\ViisonCommon\Classes\ExceptionHandling\SubscriberExceptionHandling;
use Shopware\Plugins\ViisonCommon\Classes\Plugins\SwagImportExport\AbstractDbAdapter;
use Shopware\Plugins\ViisonCommon\Classes\Plugins\SwagImportExport\DbAdapterFactory;
use Shopware\Plugins\ViisonCommon\Components\Plugins\SwagImportExportProfileService;
use Shopware_Components_Plugin_Bootstrap;

abstract class AbstractSwagImportExportIntegrationSubscriber extends AbstractBaseSubscriber
{
    use SubscriberExceptionHandling;

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

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

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

    /**
     * @param Shopware_Components_Plugin_Bootstrap $pluginBootstrap
     * @param array $profileNames
     * @param string $profileNamespaceDirectory
     * @param string $profileTreeDirectory
     */
    public function __construct(
        Shopware_Components_Plugin_Bootstrap $pluginBootstrap,
        $profileNames,
        $profileNamespaceDirectory,
        $profileTreeDirectory
    ) {
        parent::__construct($pluginBootstrap);
        $this->profileNames = $profileNames;
        $this->profileNamespaceDirectory = $profileNamespaceDirectory;
        $this->profileTreeDirectory = $profileTreeDirectory;
    }

    /**
     * @inheritdoc
     */
    public static function getSubscribedEvents()
    {
        return [
            'Shopware\\CustomModels\\ImportExport\\Repository::getProfilesListQuery::before' => 'onBeforeGetProfileListQuery',
            'Shopware_Components_SwagImportExport_Factories_CreateDbAdapter' => 'onCreateDbAdapter',
            'Shopware_Controllers_Backend_SwagImportExportProfile::getProfilesAction::after' => 'onAfterGetProfilesAction',
        ];
    }

    /**
     * Installs any custom import/export profiles if they don't exist yet and updates them if necessary.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function onBeforeGetProfileListQuery(\Enlight_Hook_HookArgs $args)
    {
        try {
            /** @var SwagImportExportProfileService $swagImportExportProfileService */
            $swagImportExportProfileService = $this->get('viison_common.swag_import_export_profile_service');
            $swagImportExportProfileService->installNewProfiles($this->profileNames, $this->profileTreeDirectory);
            $swagImportExportProfileService->updateExistingProfiles($this->profileNames, $this->profileTreeDirectory);
        } catch (\Exception $e) {
            $this->handleException($e, $args);
        }
    }

    /**
     * Tries to find a custom DB adapter for the requested adapter type and, if found, returns a new instance of it.
     *
     * @param \Enlight_Event_EventArgs $args
     * @return AbstractDbAdapter|null
     */
    public function onCreateDbAdapter(\Enlight_Event_EventArgs $args)
    {
        try {
            return $this->createDbAdapterOfType($args->adapterType);
        } catch (\Exception $e) {
            $this->handleException($e, $args);

            return null;
        }
    }

    /**
     * Adds the translations to any custom profile.
     *
     * @param \Enlight_Hook_HookArgs $args
     */
    public function onAfterGetProfilesAction(\Enlight_Hook_HookArgs $args)
    {
        try {
            $view = $args->getSubject()->View();
            if (!$view->success || count($view->data) == 0) {
                return;
            }

            // Add translations
            $data = $view->data;
            foreach ($data as &$profile) {
                if (array_key_exists($profile['name'], $this->profileNames)) {
                    $snippetNamespace = $this->get('snippets')->getNamespace(
                        $this->profileNamespaceDirectory . $profile['name']
                    );
                    $profile['translation'] = $snippetNamespace->get('title');
                }
            }
            $view->data = $data;
        } catch (\Exception $e) {
            $this->handleException($e, $args);
        }
    }

    /**
     * Creates and returns a new instance of the import/export DB adapter that matches the passed `$adapterType`.
     *
     * @param string $adapterType
     * @return AbstractDbAdapter|null
     */
    abstract protected function createDbAdapterOfType($adapterType);
}
