<?php
namespace ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra;
use ModulesGarden\Servers\ZimbraEmail\App\Enums\Zimbra;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Exceptions\ZimbraApiException;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Interfaces\ClientInterface;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Client as SoapClient;
use ModulesGarden\Servers\ZimbraEmail\App\Traits\ParamsHandler;
use ModulesGarden\Servers\ZimbraEmail\App\Traits\StorageTrait;

/**
 *
 * Created by PhpStorm.
 * User: Tomasz Bielecki ( tomasz.bi@modulesgarden.com )
 * Date: 27.08.19
 * Time: 15:05
 * Class ZimbraClientConnection
 * @property SoapClient $soap
 */
class Api
{

    use StorageTrait;
    use ParamsHandler;


    /**
     * Api constructor.
     * @param array $params
     */
    public function __construct($params = [])
    {
       $this->setParams($params);
    }

    /**
     * @param $name
     * @return ClientInterface
     * @throws \Exception
     */
    public function __get($name)
    {
        /**
         * check if class is in storage
         */
        if(!$this->getStorage()->exists(strtolower($name)))
        {
            /**
             * prepare class namespace
             */
            $class = '\\ModulesGarden\\Servers\\ZimbraEmail\\App\\Libs\\Zimbra\\Components\\Api\\'.ucfirst($name).'\\Client';

            /**
             * check if class exists or throw error
             */
            if(!class_exists($class))
            {
                throw new ZimbraApiException([
                    'message' => 'Class `'.$class.'`` does not exists',
                    'debugCode' => ZimbraApiException::UNSUPORTED_CLIENT]);
            }

            /**
             *
             * create new client class
             * prepare server parameters
             */
            $hostname = $this->params['serverhostname'] ? $this->params['serverhostname'] : $this->params['serverip'];
            $port     = $this->params['serversecure'] === 'on' ? Zimbra::SECURE_PORT : Zimbra::PORT;
            $port     = $this->params['serverport'] ? $this->params['serverport'] : $port;
            $username = $this->params['serverusername'];
            $pw       = html_entity_decode($this->params['serverpassword']);
            $auth     = $this->params['authtype'] ? $this->params['authtype'] : 'admin';

            $client = new $class($hostname, $port, $username, $pw, $auth);

            /**
             *
             * throw exception if class is not implemented
             */
            if(!($client instanceof ClientInterface))
            {
                throw new ZimbraApiException([
                    'message' => "Provided client type `{$class}` is not supported",
                    'debugCode' => ZimbraApiException::UNSUPORTED_CLIENT]);
            }

            /**
             *
             * add class to storage
             */
            $this->getStorage()->set(strtolower($name), $client);

        }else{
            /**
             *
             * get client from storage
             */
            $client = $this->getStorage()->get(strtolower($name));
        }

        /**
         *
         */
        return $client;
    }



}