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

use Chill\CalendarBundle\RemoteCalendar\Connector\MSGraph\MachineTokenStorage;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\FormatterHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use TheNetworg\OAuth2\Client\Provider\Azure;

class AzureGrantAdminConsentAndAcquireToken extends Command
{
    public function __construct(private readonly Azure $azure, private readonly ClientRegistry $clientRegistry, private readonly MachineTokenStorage $machineTokenStorage)
    {
        parent::__construct('chill:calendar:msgraph-grant-admin-consent');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        /** @var FormatterHelper $formatter */
        $formatter = $this->getHelper('formatter');
        $this->azure->scope = ['https://graph.microsoft.com/.default'];
        $authorizationUrl = explode('?', $this->azure->getAuthorizationUrl(['prompt' => 'admin_consent']));

        // replace the first part by the admin consent authorization url
        $authorizationUrl[0] = strtr('https://login.microsoftonline.com/{tenant}/adminconsent', ['{tenant}' => $this->azure->tenant]);

        $output->writeln('Go to the url');
        $output->writeln(implode('?', $authorizationUrl));
        $output->writeln('Authenticate as admin, and grant admin consent');

        // not necessary ?
        $helper = $this->getHelper('question');
        $question = new ConfirmationQuestion('Access granted ?');

        if (!$helper->ask($input, $output, $question)) {
            $messages = ['No problem, we will wait for you', 'Grant access and come back here'];
            $output->writeln($formatter->formatBlock($messages, 'warning'));

            return Command::SUCCESS;
        }

        $token = $this->machineTokenStorage->getToken();

        $messages = ['Token acquired!', 'We could acquire a machine token successfully'];
        $output->writeln($formatter->formatBlock($messages, 'success'));

        $output->writeln('Token information:');
        $output->writeln($token->getToken());
        $output->writeln('Expires at: '.$token->getExpires());
        $output->writeln('To inspect the token content, go to https://jwt.ms/#access_token='.urlencode($token->getToken()));

        return Command::SUCCESS;
    }
}
