<?php
namespace Fifa\ConnectServiceBus\Sdk\Authentication;

use Fifa\ConnectServiceBus\Sdk\Authentication\Model\AuthenticationInformation;
use Fifa\ConnectServiceBus\Sdk\Authentication\Model\Token;
use Fifa\ConnectServiceBus\Sdk\Utils\SerializableCache;

/**
 * Class TokenCache
 * @package Fifa\ConnectServiceBus\Sdk\Authentication
 */
class TokenCache implements TokenCacheInterface
{
    /**
     * @var SerializableCache
     */
    private $serializableCache;

    /**
     * @var Token
     */
    private $token;

    /**
     * @var AuthenticationInformation
     */
    private $authenticationInformation;

    /**
     * Constructor
     *
     * @param AuthenticationInformation $authenticationInformation
     * @param CacheStorageInterface $cacheStorage
     * @param int $expirationTimeSpanInSeconds
     */
    public function __construct(AuthenticationInformation $authenticationInformation, CacheStorageInterface $cacheStorage, int $expirationTimeSpanInSeconds)
    {
        $this->serializableCache = new SerializableCache($cacheStorage);
        $this->serializableCache->setExpirationTimeSpanInSeconds($expirationTimeSpanInSeconds);
        $this->authenticationInformation = $authenticationInformation;
    }

    /**
     * Returns token object that is stored in cache
     *
     * @return Token
     */
    public function getTokenFromCache(): ?Token
    {
        if (!$this->isValid()) {
            return null;
        }
        return $this->token;
    }

    /**
     * Store given token object into cache
     *
     * @param Token $token
     * @return TokenCacheInterface
     */
    public function storeCache(Token $token): TokenCacheInterface
    {
        $this->serializableCache->put($this->authenticationInformation, $token);
        $this->token = $token;

        return $this;
    }

    /**
     * Checks whether stored cache is still valid
     *
     * @return bool
     */
    private function isValid(): bool
    {
        if (!isset($this->token) || !$this->token) {
            $token = $this->serializableCache->get($this->authenticationInformation);
            if(isset($token) && $token) {
                $this->token = $token;
            } else {
                return false;
            }
        }

        $diff = $this->token->getExpiresAt() - time();

        return $diff >= $this->serializableCache->getExpirationTimeSpanInSeconds();
    }
}