<?php

/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       https://www.life-style.de
 */

namespace LifeStyle\DH\AccessControlBundle\ObjectService;

use Closure;
use Gmponos\GuzzleLogger\Middleware\LoggerMiddleware;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\HandlerStack;
use LifeStyle\DH\AccessControlBundle\Configuration\ClientConfiguration;
use Psr\Http\Message\RequestInterface;
use Psr\Log\LoggerInterface;

/**
 * Class ClientFactory
 *
 * @copyright  2019 Lifestyle Webconsulting GmbH
 * @link       https://www.life-style.de
 * @package LifeStyle\DH\AccessControlBundle\ObjectService
 */
class ClientFactory
{
    /**
     * @var ClientConfiguration
     */
    private $configuration;

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

    /**
     * ClientFactory constructor.
     * @param ClientConfiguration $configuration
     * @param LoggerInterface $logger
     */
    public function __construct(ClientConfiguration $configuration, LoggerInterface $logger)
    {
        $this->configuration = $configuration;
        $this->logger = $logger;
    }

    /**
     * @return ClientInterface
     */
    public function createClient(): ClientInterface
    {
        $handlerStack = HandlerStack::create();

        $handlerStack->remove('cookies');
        $handlerStack->push(new LoggerMiddleware($this->logger));
        $handlerStack->before('prepare_body', $this->addHeader('Accept', 'application/json'));
        $handlerStack->before('prepare_body', $this->addHeader('Content-Type', 'application/json'));
        $handlerStack->before('prepare_body', $this->addHeader('X-Auth-Token', $this->configuration->getAuthToken()));

        return new Client([
            'handler' => $handlerStack,
            'base_uri' => $this->configuration->getBaseUrl(),
        ]);
    }

    /**
     * @param string $header
     * @param string $value
     * @return Closure
     */
    private function addHeader(string $header, string  $value): Closure
    {
        return function (callable $handler) use ($header, $value) {
            return function (
                RequestInterface $request,
                array $options
            ) use ($handler, $header, $value) {
                $request = $request->withHeader($header, $value);
                return $handler($request, $options);
            };
        };
    }
}
