<?php

/**
 * Chill is a software for social workers.
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\CalendarBundle\RemoteCalendar\DependencyInjection;

use Chill\CalendarBundle\Command\AzureGrantAdminConsentAndAcquireToken;
use Chill\CalendarBundle\Command\MapAndSubscribeUserCalendarCommand;
use Chill\CalendarBundle\Controller\RemoteCalendarConnectAzureController;
use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MachineHttpClient;
use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MachineTokenStorage;
use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceReaderInterface;
use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MSUserAbsenceSync;
use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraphRemoteCalendarConnector;
use Chill\CalendarBundle\RemoteCalendar\Connector\NullRemoteCalendarConnector;
use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use TheNetworg\OAuth2\Client\Provider\Azure;

class RemoteCalendarCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        $config = $container->getParameter('chill_calendar');

        if (true === $config['remote_calendars_sync']['microsoft_graph']['enabled']) {
            $connector = MSGraphRemoteCalendarConnector::class;

            $container->setAlias(HttpClientInterface::class.' $machineHttpClient', MachineHttpClient::class);
        } else {
            $connector = NullRemoteCalendarConnector::class;
            // remove services which cannot be loaded
            $container->removeDefinition(MapAndSubscribeUserCalendarCommand::class);
            $container->removeDefinition(AzureGrantAdminConsentAndAcquireToken::class);
            $container->removeDefinition(RemoteCalendarConnectAzureController::class);
            $container->removeDefinition(MachineTokenStorage::class);
            $container->removeDefinition(MachineHttpClient::class);
            $container->removeDefinition(MSGraphRemoteCalendarConnector::class);
            $container->removeDefinition(MSUserAbsenceReaderInterface::class);
            $container->removeDefinition(MSUserAbsenceSync::class);
        }

        if (!$container->hasAlias(Azure::class) && $container->hasDefinition('knpu.oauth2.client.azure')) {
            $container->setAlias(Azure::class, 'knpu.oauth2.provider.azure');
        }

        foreach ([
            NullRemoteCalendarConnector::class,
            MSGraphRemoteCalendarConnector::class, ] as $serviceId) {
            if ($connector === $serviceId) {
                $container->getDefinition($serviceId)
                    ->setDecoratedService(RemoteCalendarConnectorInterface::class);
            } else {
                // keep the container lighter by removing definitions
                if ($container->hasDefinition($serviceId)) {
                    $container->removeDefinition($serviceId);
                }
            }
        }
    }
}
