<?php
namespace Fifa\ConnectServiceBus\Sdk;

use Exception;
use Fifa\ConnectServiceBus\Sdk\Api\ApiException;
use Fifa\ConnectServiceBus\Sdk\Api\Resource\CertificateApi;
use Fifa\ConnectServiceBus\Sdk\Authentication\Model\ClientCredentials;
use Fifa\ConnectServiceBus\Sdk\Environment\EnvironmentInterface;
use Fifa\ConnectServiceBus\Sdk\Exception\FifaConnectServiceBusSdkException;
use Fifa\ConnectServiceBus\Sdk\ExceptionHandler\ExceptionHandler;
use Fifa\ConnectServiceBus\Sdk\ExceptionHandler\Handler\DataNotFoundHandler;
use Fifa\ConnectServiceBus\Sdk\ExceptionHandler\Handler\UnauthorizedRequestHandler;
use Fifa\ConnectServiceBus\Sdk\Utils\ToStringConverter;
use InvalidArgumentException;
use Psr\Log\LoggerInterface;

/**
 * Class FifaConnectServiceBusCertificateClient
 * @package Fifa\ConnectServiceBus\Sdk
 */
class FifaConnectServiceBusCertificateClient implements FifaConnectServiceBusCertificateClientInterface
{
    /**
     * @var CertificateApi
     */
    private $certificateApi;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * Constructor
     *
     * @param EnvironmentInterface $environment
     * @param ClientCredentials $clientCredentials
     * @param LoggerInterface $logger
     */
    public function __construct(EnvironmentInterface $environment, ClientCredentials $clientCredentials, LoggerInterface $logger)
    {
        $this->logger = $logger;
        $this->certificateApi = $environment->getCertificateApi($clientCredentials);
    }

    /**
     * @inheritDoc
     */
    public function uploadCertificate(string $rawData): void
    {
        if (strlen($rawData) === 0) {
            throw new InvalidArgumentException('Certificate file path is incorrect');
        }

        try {
            $this->logger->debug('Uploading certificate');

            $response = $this->certificateApi->certificateUploadWithHttpInfo(
                json_encode(base64_encode($rawData))
            );

            $this->logger->debug('Uploading certificate has completed successfully', array('response' => ToStringConverter::arrayToString($response)));
        }
        catch (Exception $e) {
            $this->logger->error('Unexpected error when trying to upload a certificate', array('exception' => $e->__toString()));
            throw ExceptionHandler::create($e);
        }
    }

    /**
     * @inheritDoc
     */
    public function downloadCertificate(string $queueIdentifier): string
    {
        try {
            $this->logger->debug('Downloading certificate');
            $certificate = $this->certificateApi->certificateDownloadByQueueidentifier($queueIdentifier);

            if (!is_string($certificate) || strlen($certificate) < 2) {

                $message = 'Certificate is not a valid string.';
                $this->logger->error($message);
                throw new FifaConnectServiceBusSdkException(new ApiException($message), $message);
            }

            $this->logger->debug('Downloading certificate has completed successfully', array('response' => $certificate));
            return base64_decode($certificate);
        }
        catch (Exception $e) {
            $this->logger->error('Unexpected error when trying to download a certificate', array('exception' => $e->__toString()));
            throw ExceptionHandler::create($e, new DataNotFoundHandler(), new UnauthorizedRequestHandler());
        }
    }
}