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

use Shopware\Components\Model\ModelManager;
use Shopware\CustomModels\ImportExport\Profile;
use Symfony\Component\DependencyInjection\Container;

class SwagImportExportProfileService
{
    /**
     * @var ModelManager
     */
    protected $entityManager;

    /**
     * @param Container $container
     */
    public function __construct(Container $container)
    {
        // Force loading the SwagImportExport plugin by requesting one of its services. Unfortunately, this is necessary
        // because SwagImportExport does not subscribe to onStartDispatch, so it's not guaranteed that its namespaces
        // are available when plugin updates are performed.
        $container->get('swag_import_export.profile_service');

        $this->entityManager = $container->get('models');
    }

    /**
     * Installs any custom profiles that are not already in the database.
     *
     * @param array $profiles
     * @param string $profileTreeDirectory
     */
    public function installNewProfiles($profiles, $profileTreeDirectory)
    {
        $repository = $this->entityManager->getRepository(Profile::class);
        $newProfiles = [];
        foreach ($profiles as $name => $type) {
            // Try to find the profile
            $profile = $repository->findOneBy([
                'name' => $name,
            ]);
            if ($profile) {
                continue;
            }

            // Create a new profile
            $profile = new Profile();
            $profile->setName($name);
            // Set 'default' to prevent users from deleting the profile
            $profile->setDefault(true);
            $this->updateProfile($profile, $type, $profileTreeDirectory);

            $this->entityManager->persist($profile);
            $newProfiles[] = $profile;
        }

        // Save new profiles if any were added
        if (count($newProfiles) > 0) {
            $this->entityManager->flush($newProfiles);
        }
    }

    /**
     * Updates all existing custom profiles.
     *
     * @param array $profiles
     * @param string $profileTreeDirectory
     * @return array
     */
    public function updateExistingProfiles($profiles, $profileTreeDirectory)
    {
        // Make sure all custom profiles are up to date
        $repository = $this->entityManager->getRepository(Profile::class);
        $updatedProfiles = [];
        foreach ($profiles as $name => $type) {
            /** @var Profile $profile */
            $profile = $repository->findOneBy([
                'name' => $name,
            ]);
            if (!$profile) {
                continue;
            }

            $this->updateProfile($profile, $type, $profileTreeDirectory);
            $updatedProfiles[] = $profile;
        }

        // Save changes if any were updated
        if (count($updatedProfiles) > 0) {
            $this->entityManager->flush($updatedProfiles);
        }

        return $updatedProfiles;
    }

    /**
     * Updates the $type of the given $profile, loads its respective configuration file and saves it in the profile.
     *
     * @param Profile $profile
     * @param string $type
     * @param string $profileTreeDirectory
     */
    protected function updateProfile($profile, $type, $profileTreeDirectory)
    {
        $profile->setType($type);
        $treePath = $profileTreeDirectory . $profile->getName() . '.json';
        if (file_exists($treePath)) {
            $tree = file_get_contents($treePath);
            $tree = preg_replace('/\\s+/', '', $tree);
            $profile->setTree($tree);
        }
    }
}
