<?php

declare(strict_types=1);

/**
 * Created by Aurélien RICHAUD (13/02/2018 17:04).
 */
require_once __DIR__ . \DIRECTORY_SEPARATOR
    . '..' . \DIRECTORY_SEPARATOR
    . '..' . \DIRECTORY_SEPARATOR
    . 'classes' . \DIRECTORY_SEPARATOR . 'OAuthClient.php';
require_once __DIR__ . \DIRECTORY_SEPARATOR
    . '..' . \DIRECTORY_SEPARATOR
    . '..' . \DIRECTORY_SEPARATOR
    . 'classes' . \DIRECTORY_SEPARATOR . 'OAuthAuthCode.php';
require_once __DIR__ . \DIRECTORY_SEPARATOR
    . '..' . \DIRECTORY_SEPARATOR
    . '..' . \DIRECTORY_SEPARATOR
    . 'classes' . \DIRECTORY_SEPARATOR . 'OAuthAccessToken.php';

class AdminMyVetShopCliniqueSSOTokenController extends AdminController
{
    public function init(): void
    {
        // ///////////////////////////////////////
        // Enregistre les informations OAuth dans le cookie
        $code = Tools::getValue('code');
        $grant_type = Tools::getValue('grant_type');
        $client_id = Tools::getValue('client_id');
        $client_secret = Tools::getValue('client_secret');
        $redirect_uri = Tools::getValue('redirect_uri');

        if (!$client_id && !$client_secret && $_SERVER['PHP_AUTH_USER'] && $_SERVER['PHP_AUTH_PW']) {
            $client_id = $_SERVER['PHP_AUTH_USER'];
            $client_secret = $_SERVER['PHP_AUTH_PW'];
        }

        // Paramètres obligatoires
        if (
            !\is_string($code)
            || !\is_string($grant_type)
            || !\is_string($client_id)
            || !\is_string($client_secret)
            || !\is_string($redirect_uri)
            || !$code
            || !$grant_type
            || !$client_id
            || !$client_secret
            || !$redirect_uri) {
            \header('HTTP/1.0 400 Bad Request');
            if (!$code) {
                echo \json_encode(['error' => 'No code']);
            } elseif (!$grant_type) {
                echo \json_encode(['error' => 'No grant_type']);
            } elseif (!$client_id) {
                echo \json_encode(['error' => 'No client_id']);
            } elseif (!$client_secret) {
                echo \json_encode(['error' => 'No client_secret']);
            } elseif (!$redirect_uri) {
                echo \json_encode(['error' => 'No redirect_uri']);
            }
            exit;
        }

        try {
            $authCode = OAuthAuthCode::getByToken($code);

            $client = OAuthClient::getByRandomId($client_id);
        } catch (PrestaShopDatabaseException $e) {
            $authCode = null;
            $client = null;
        } catch (PrestaShopException $e) {
            $authCode = null;
            $client = null;
        }

        // ///////////////////////////////////////
        // AuthCode invalide
        if (!$authCode || !$client || $authCode->client_id != $client->id_oauth_client) {
            \header('HTTP/1.0 400 Bad Request');
            exit;
        }

        // ///////////////////////////////////////
        // Client secret
        if ($client->secret != $client_secret) {
            \header('HTTP/1.0 403 Forbidden');
            echo 'Invalid client secret';
            exit;
        }

        // ///////////////////////////////////////
        // RedirectUri invalide
        if (!\in_array($redirect_uri, \explode(',', $client->redirect_uris))) {
            \header('HTTP/1.0 403 Forbidden');
            exit;
        }

        // ///////////////////////////////////////
        // / Création d'un AccessToken
        $accessToken = new OAuthAccessToken();
        $accessToken->client_id = (string) $authCode->client_id;
        $accessToken->id_employee = $authCode->id_employee;
        $accessToken->redirect_uri = $redirect_uri;
        $accessToken->created = \time();
        $accessToken->expires = \time() + 365 * 24 * 60 * 60; // 1 an

        // Sauvegarde l'AuthCode
        try {
            $accessToken->save();

            $authCode->delete();
        } catch (PrestaShopException $e) {
            \header('HTTP/1.0 500 Internal Server Error');
            exit;
        }

        // ///////////////////////////////////////
        // / Redirrige vers l'URL de retour
        \header('Content-Type: application/json');
        echo \json_encode(
            [
                'access_token' => $accessToken->token,
                'expires_in' => $accessToken->expires - \time(),
                'token_type' => 'Bearer',
                'scope' => '',
            ]
        );
        exit;
    }
}
