<?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 Pickware\PickwareAutoloadInstaller;

use Composer\Composer;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Factory;
use Composer\Installer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;

class PickwareAutoloadInstallerPlugin implements PluginInterface, EventSubscriberInterface
{
    /**
     * @var IOInterface
     */
    private $io;

    public function activate(Composer $composer, IOInterface $io)
    {
        $this->io = $io;
    }

    public function deactivate(Composer $composer, IOInterface $io)
    {
    }

    public function uninstall(Composer $composer, IOInterface $io)
    {
    }

    public static function getSubscribedEvents()
    {
        return [
            'post-install-cmd' => 'onInstallOrUpdate',
            'post-update-cmd' => 'onInstallOrUpdate',
        ];
    }

    public function onInstallOrUpdate()
    {
        $dependencyDirectories = $this->findPickwareAutoloadDependencyDirectories();
        foreach ($dependencyDirectories as $dependencyDirectory) {
            $dependencyComposerJsonPath = $dependencyDirectory . '/composer.json';
            if (!file_exists($dependencyComposerJsonPath)) {
                continue;
            }

            $this->runComposerInstallInDirectory($dependencyDirectory);
        }
    }

    private function runComposerInstallInDirectory($dependencyDirectory)
    {
        $dependencyComposerJsonPath = $dependencyDirectory . '/composer.json';
        $factory = new Factory();
        $dependencyComposer = $factory->createComposer(
            $this->io,
            $dependencyComposerJsonPath,
            false,
            $dependencyDirectory
        );
        if (method_exists($dependencyComposer->getInstallationManager(), 'setOutputProgress')) {
            $dependencyComposer->getInstallationManager()->setOutputProgress(true);
        } elseif (method_exists($dependencyComposer->getDownloadManager(), 'setOutputProgress')) {
            $dependencyComposer->getDownloadManager()->setOutputProgress(true);
        }
        $install = Installer::create($this->io, $dependencyComposer);
        $install
            ->setDevMode(false)
            ->setOptimizeAutoloader(true)
            ->setUpdate(false)
            ->setIgnorePlatformRequirements(true);

        $install->run();
    }

    private function findPickwareAutoloadDependencyDirectories()
    {
        $pickwareAutoloadDirectories = $this->findPickwareAutoloadDirectories();
        if (count($pickwareAutoloadDirectories) === 0) {
            return [];
        }

        $dependencyDirectories = array_map(function ($pickwareAutoloadDirectory) {
            return array_map(
                function ($directoryName) use ($pickwareAutoloadDirectory) {
                    return $pickwareAutoloadDirectory . '/' . $directoryName;
                },
                array_values(array_diff(scandir($pickwareAutoloadDirectory), ['..', '.']))
            );
        }, $pickwareAutoloadDirectories);

        // FlatMap the nested array structure so we get only the dependency directories
        return array_merge(...$dependencyDirectories);
    }

    private function findPickwareAutoloadDirectories()
    {
        $pluginRootDirectory = getcwd();
        $pickwareAutoloadDirectories = [
            $pluginRootDirectory . '/pickware-autoload',
            $pluginRootDirectory . '/ViisonCommon/pickware-autoload',
        ];

        return array_values(array_filter($pickwareAutoloadDirectories, 'file_exists'));
    }
}
