<?php

namespace onespace\tools\components\clients;

use DateTimeImmutable;
use Lcobucci\JWT\Token;
use Yii;
use yii\helpers\ArrayHelper;
use yii\httpclient\Client;
use yii\httpclient\Request;

/**
 * Connect to the OS Service Client to connect to various OS services.
 * 
 * Must be injected in the config as a component
 * 
 * @deprecated for library
 */
class OneSpaceServiceClient extends Client {
    public $serviceGuid;
    public $serviceKey;
    public $authTokenCacheKey = 'serviceAuthToken';

    /**
     * @return Request request instance.
     * @throws \yii\base\InvalidConfigException
     */
    public function createRequest() {
        $config = $this->requestConfig;
        if (!isset($config['class'])) {
            $config['class'] = Request::class;
        }
        $config['client'] = $this;
        /** @var Request $request */
        $request = Yii::createObject($config);
        $request->setFormat(Client::FORMAT_JSON);

        // add auth headers
        $token = $this->loadServiceToken();

        // add the required token header
        $request->addHeaders(['Service-Authorization' => $token]);

        return $request;
    }

    public function loadServiceToken() {
        $token = Yii::$app->cache->get($this->authTokenCacheKey);
        if (!$token) {
            // request a new token
            // call the endpoint for the token
            $url = Yii::$app->params['serviceUrls']['serviceApi'] . 'token';
            $client = new Client();
            $response = $client->post($url, ['data' => ['login' => $this->serviceGuid, 'password' => $this->serviceKey]])
                ->setFormat(Client::FORMAT_JSON)
                ->send();
            if ($response->isOk) {
                Yii::info("Got response: " . json_encode($response->data), __METHOD__);
                $tokenString = ArrayHelper::getValue($response->data, 'data.token');

                // calculate the cache expiry time based on the token expiry time
                /** @var Token $token */
                $token = Yii::$app->jwt->getParser()->parse((string) $tokenString); // Parses from a string

                $tokenExpiry = $token->claims()->get('exp');
                $duration = null;
                if ($tokenExpiry != null) {
                    if ($tokenExpiry instanceof DateTimeImmutable) {
                        $tokenExpiry = $tokenExpiry->getTimestamp();
                    }
                    $duration = $tokenExpiry - time();
                }

                // save the token to the cache
                Yii::$app->cache->set($this->authTokenCacheKey, $tokenString, $duration);
                return $tokenString;
            } else {
                // echo "HTTP error! ". $response->statusCode . ' - ' . json_encode($response->data)."\n";
                Yii::info("HTTP error! " . $response->statusCode . ' - ' . json_encode($response), __METHOD__);
            }
        } else {
            return $token;
        }
    }
}
