<?php

namespace Velis\Microsoft;

use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Provider\GenericProvider;
use Velis\Debug;
use Velis\Exception;

class TokenProvider
{
    private string $tenantId;


    public function __construct(string $tenantId)
    {
        $this->tenantId = $tenantId;
    }
    /**
     * @return Token
     */
    public function getToken(string $clientId, string $clientSecret, string $scope): Token
    {

        $provider = $this->getProvider($clientId, $clientSecret);

        try {
            $accessToken = $provider->getAccessToken('client_credentials', [
                'scope' => $scope
            ]);

            $values = $accessToken->getValues();
            $expiresIn = $values['ext_expires_in'];

            if (!isset($expiresIn)) {
                $expiresIn = $accessToken->getExpires() - time();
            }

            return new Token(
                $accessToken->getToken(),
                $expiresIn,
                $accessToken->getExpires(),
                $values['token_type']
            );
        } catch (IdentityProviderException $e) {
            Exception::raise('Could not get access token: ' . $e->getMessage());
            Debug::reportException($e);
            throw $e;
        }
    }

    /**
     * @return GenericProvider
     */
    protected function getProvider(string $clientId, string $clientSecret): GenericProvider
    {
        $provider = new GenericProvider([
            'clientId' => $clientId,
            'clientSecret' => $clientSecret,
            'urlAuthorize' => 'https://login.microsoftonline.com/' . $this->tenantId . '/oauth2/v2.0/authorize',
            'urlAccessToken' => 'https://login.microsoftonline.com/' . $this->tenantId . '/oauth2/v2.0/token',
            'urlResourceOwnerDetails' => 'https://login.microsoftonline.com/' . $this->tenantId . '/oauth2/v2.0/token'
        ]);

        return $provider;
    }
}
