<?php

namespace Velis\Test\Microsoft;

use Velis\Cache\CacheInterface;
use Velis\Microsoft\Token;
use Velis\Microsoft\TokenProvider;
use Velis\Microsoft\TokenService;
use Velis\TestCase;


class TokenServiceTest extends TestCase
{
    /**
     * @return void
     * @dataProvider provideTestDataForGetToken
     */
    public function testGetToken(TokenProvider $tokenProvider, CacheInterface $cache, ?string $expected)
    {
        $tokenService = new TokenService($tokenProvider, $cache);
        $token = $tokenService->getToken('clientId', 'clientSecret', 'scope');

        $this->assertEquals($expected, $token);
    }


    public function provideTestDataForGetToken()
    {
        // Token in cache
        $tokenInCacheProvider = $this->createMock(TokenProvider::class);
        $tokenInCacheProvider->expects($this->never())->method('getToken');

        $inCache = $this->createMock(CacheInterface::class);
        $inCache->expects($this->once())->method('has')->willReturn(true);
        $inCache->expects($this->once())->method('get')->willReturn(new Token('token', 3600, time() + 3600, 'type'));

        // Token not in cache
        $tokenNotInCacheProvider = $this->createMock(TokenProvider::class);
        $tokenNotInCacheProvider->expects($this->once())->method('getToken')->willReturn(new Token('token', 3600, time() + 3600, 'type'));

        $notInCache = $this->createMock(CacheInterface::class);
        $notInCache->expects($this->once())->method('has')->willReturn(false);
        $notInCache->expects($this->never())->method('get')->willReturn(null);
        $notInCache->expects($this->once())->method('set')->willReturn(true);

        // Token in cache but expired
        $tokenInCacheButExpiredProvider = $this->createMock(TokenProvider::class);
        $tokenInCacheButExpiredProvider->expects($this->once())->method('getToken')->willReturn(new Token('token', 3600, time() - 3600, 'type'));
        
        $inCacheButExpired = $this->createMock(CacheInterface::class);
        $inCacheButExpired->expects($this->once())->method('has')->willReturn(true);
        $inCacheButExpired->expects($this->once())->method('get')->willReturn(new Token('token', 3600, time() - 3600, 'type'));
        $inCacheButExpired->expects($this->once())->method('set')->willReturn(true);

        return [
            'token in cache' => [$tokenInCacheProvider, $inCache, 'token'],
            'token not in cache' => [$tokenNotInCacheProvider, $notInCache, 'token'],
            'token in cache but expired' => [$tokenInCacheButExpiredProvider, $inCacheButExpired, 'token'],
        ];
    }
}
