      1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:
                 23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:
                 39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:
                 59:  60:
                 61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143:

    <?php

    /*
     * This file is part of the affilinet Product Data PHP SDK.
     *
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */

    namespace Affilinet\ProductData;

    use Affilinet\ProductData\Exceptions\AffilinetProductWebserviceException;
    use Affilinet\ProductData\HttpClient\GuzzleClient;
    use Affilinet\ProductData\HttpClient\HttpClientInterface;
    use Affilinet\ProductData\Requests\RequestInterface;
    use GuzzleHttp\Client;
    use GuzzleHttp\ClientInterface;
    use Monolog\Handler\SyslogHandler;
    use Monolog\Logger;

    /**
     * Client to send requests to the API
     */
    class AffilinetClient
    {

        /**
         * @const string The name of the environment variable that contains your Affilinet Publisher ID
         */
        const PUBLISHER_ID_ENV_NAME = 'AFFILINET_PUBLISHER_ID';

        /**
         * @const string The name of the environment variable that contains your Affilinet Publisher Webservice Password
         */
        const PRODUCT_WEBSERVICE_PASSWORD_ENV_NAME = 'AFFILINET_PRODUCT_WEBSERVICE_PASSWORD';

        /**
         * @var $publisherId string
         */
        public $publisherId;

        /**
         * @var $productDataWebservicePassword string
         */
        public $productDataWebservicePassword;

        /**
         * @var $httpClient HttpClientInterface
         */
        public $httpClient;

        /**
         * @var Logger
         */
        private $log;

        /**
         * PublisherClient constructor.
         * @param  array                               $config
         * @throws AffilinetProductWebserviceException
         */
        public function __construct(array $config = [])
        {
            $config = array_merge([
                'publisher_id' => getenv(static::PUBLISHER_ID_ENV_NAME),
                'product_webservice_password' => getenv(static::PRODUCT_WEBSERVICE_PASSWORD_ENV_NAME)
            ], $config);

            if (!$config['publisher_id']) {
                throw new AffilinetProductWebserviceException('Required "publisher_id" key not supplied in config and could not find fallback environment variable "' . static::PUBLISHER_ID_ENV_NAME . '"');
            }
            if (!$config['product_webservice_password']) {
                throw new AffilinetProductWebserviceException('Required "product_webservice_password" key not supplied in config and could not find fallback environment variable "' . static::PRODUCT_WEBSERVICE_PASSWORD_ENV_NAME . '"');
            }
            if (isset($config['log'])) {
                $this->log = $config['log'];
            } else {
                $this->log = new Logger('affilinet-publisher-sdk');
                $this->log->pushHandler(new SyslogHandler('affilinet'));
            }

            if (isset($config['http_client'])) {
                if ($config['http_client'] instanceof ClientInterface) {
                    $this->httpClient = new GuzzleClient($config['http_client']);
                } elseif (!$config['http_client'] instanceof HttpClientInterface) {
                    throw new \InvalidArgumentException('Config parameter "http_client" has to implement Affilinet\HttpClient\HttpClientInterface');
                } else {
                    $this->httpClient = $config['http_client'];
                }

            } else {
                $this->httpClient = new GuzzleClient(new Client());
            }

            $this->publisherId = $config['publisher_id'];
            $this->productDataWebservicePassword = $config['product_webservice_password'];

        }

        /**
         * @return string
         */
        public function getPublisherId()
        {
            return $this->publisherId;
        }

        /**
         * @return string
         */
        public function getProductDataWebservicePassword()
        {
            return $this->productDataWebservicePassword;
        }

        /**
         * @return Logger
         */
        public function getLog()
        {
            return $this->log;
        }

        /**
         * @return HttpClientInterface
         */
        public function getHttpClient()
        {
            return $this->httpClient;
        }

        /**
         * @param  RequestInterface            $request
         * @return Responses\ResponseInterface
         */
        public function send(RequestInterface $request)
        {
            return $request->send();

        }

    }