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

use Psr\Log\LoggerInterface;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;

class PluginStructureIntegrity
{
    /**
     * @var string $pluginRootPath
     */
    private $pluginRootPath;

    /**
     * @var LoggerInterface $logger
     */
    private $logger;

    /**
     * @param string $pluginRootPath
     * @param LoggerInterface $logger
     */
    public function __construct($pluginRootPath, LoggerInterface $logger)
    {
        $this->pluginRootPath = realpath($pluginRootPath) . '/';
        $this->logger = $logger;
    }

    /**
     * Checks the plugin root path for a 'plugin.summary' file and, if it exists, compares the paths of
     * all files contained in the plugin with the paths listed in the summary. If an existing file is
     * not listed in the summary, it is removed from disk.
     */
    public function removeObsoleteFiles()
    {
        // Try to find a 'plugin.summary' file
        $summaryFilePath = $this->pluginRootPath . 'plugin.summary';
        if (!file_exists($summaryFilePath)) {
            return;
        }

        // Read the paths of all required plugin files from the summary
        $requiredPluginFiles = [];
        $handle = fopen($summaryFilePath, 'r');
        if ($handle) {
            $line = fgets($handle);
            while ($line !== false) {
                $requiredPluginFiles[] = str_replace('/./', '/', ($this->pluginRootPath . trim($line, "\n")));
                $line = fgets($handle);
            }
            fclose($handle);
        } else {
            $this->logger->error('ViisonCommon: Failed to read "plugin.summary" file.');

            return;
        }

        // Delete all files from the plugin directory that are not required (contained in the summary)
        $filesystem = new Filesystem();
        $fileIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->pluginRootPath), RecursiveIteratorIterator::SELF_FIRST);
        foreach ($fileIterator as $file) {
            if (!$file->isFile() || in_array($file->getPathname(), $requiredPluginFiles)) {
                continue;
            }
            try {
                $filesystem->remove($file->getPathname());
            } catch (IOException $e) {
                $this->logger->error('ViisonCommon: Failed to remove obsolete file from plugin. ' . $e->getMessage(), ['exception' => $e, 'file' => $file->getPathname()]);
            }
        }
    }
}
