<?php

namespace ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Repository;


use ModulesGarden\Servers\ZimbraEmail\App\Enums\Size;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Interfaces\AbstractApiClient;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Interfaces\AbstractRepository;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Models\Account;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Models\AccountAlias;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Models\Domain;

/**
 *
 * Created by PhpStorm.
 * User: Tomasz Bielecki ( tomasz.bi@modulesgarden.com )
 * Date: 10.09.19
 * Time: 08:28
 * Class Accounts
 */
class Accounts extends AbstractRepository
{
    const NO_COS_INDEX = 'default';

    /**
     * get all account for domain
     * @param $name
     * @return mixed
     */
    public function getByDomainName($name)
    {
        $domain = new Domain();
        $domain->setName($name);

        $result = $this->getClient()->account->getAllByDomain($domain);

        $accounts = $result->getResponseBody()['GETALLACCOUNTSRESPONSE']['ACCOUNT'];
        /**
         * API return one or araay with accounts
         */
        $tmp = [];
        if(isset($accounts['NAME']))
        {
            $tmpAccount =  new Account($accounts);

            /**
             * skip ZiImbra default account
             */
            if (strpos($tmpAccount->getName(), 'galsync@') !== false)
            {
                return [];
            }
            $tmp[$tmpAccount->getId()] = $tmpAccount;
        }else{
            foreach($accounts as $account)
            {
                $tmpAccount =  new Account($account);

                /**
                 * skip ZiImbra default account
                 */
                if (strpos($tmpAccount->getName(), 'galsync@') !== false)
                {
                    continue;
                }


                $tmp[$tmpAccount->getId()] = $tmpAccount;
            }
        }

       return $tmp;
    }

    /**
     * @param $name
     * @return mixed
     */
    public function getGroupedByCos($name)
    {
        $accounts = $this->getByDomainName($name);
        foreach($accounts as $account)
        {
            /* @var $account Account*/
            $cosId = $account->getDataResourceA(Account::ATTR_CLASS_OF_SERVICE_ID);
            $key = $cosId ? $cosId : self::NO_COS_INDEX;

            $tmp[$key][] = $account;
        }

        return $tmp;
    }

    /**
     * @param $name
     * @return mixed
     */
    public function getMailboxes($name)
    {
        $accounts = $this->getByDomainName($name);

        foreach($accounts as $key => $account)
        {
            /* @var $account Account*/
            if (strpos($account->getName(), 'galsync@') !== false)
            {
                unset($accounts[$key]);
                continue;
            }

        }

        return $accounts;
    }

    /**
     * @param $id
     * @return Account
     */
    public function getAccountInfoById($id)
    {
        $account = new Account();
        $account->setId($id);

        $result = $this->getClient()->account->getAccountInfo($account);

        if(!$result->getLastError())
        {
            $body = $result->getResponseBody();
            $result =  $account->fill($body['GETACCOUNTINFORESPONSE']);
            $result->setName($body['GETACCOUNTINFORESPONSE']['NAME']['DATA']);
            return $result;
        }

        return $result;
    }

    /**
     * @param $id
     * @return Account
     */
    public function getAccountOptionsById($id)
    {
        $account = new Account();
        $account->setId($id);

        $result = $this->getClient()->account->getAccountOptions($account);

        if(!$result->getLastError())
        {
            $body = $result->getResponseBody();
            return $account->fill($body['GETACCOUNTRESPONSE']['ACCOUNT']);
        }

        return $result;
    }

    /**
     * @param $name
     * @return mixed
     */
    public function getUsages($name)
    {
        $domain = new Domain();
        $domain->setName($name);

        $result = $this->getClient()->domain->getDomainUsages($domain);

        $accounts = $result->getResponseBody()['GETQUOTAUSAGERESPONSE']['ACCOUNT'];

        /**
         * API return one or araay with accounts
         */
        if(isset($accounts['NAME']))
        {
            $tmpAccount =  new Account($accounts);
            $tmp[$tmpAccount->getId()] = $tmpAccount;
        }else{
            foreach($accounts as $account)
            {
                $tmpAccount =  new Account($account);
                $tmp[$tmpAccount->getId()] = $tmpAccount;
            }
        }

        return $tmp;
    }

    /**
     * @description return usages of all accounts
     * @param $name
     * @return float
     */
    public function getFullUsages($name)
    {
        /**
         * count Usages
         */
        foreach($this->getUsages($name) as $acc)
        {
            $used += (float) $acc->getUsed();
        }
        $used = round($used / Size::B_TO_MB, 2);

        return $used;
    }

    /**
     * @param $domain
     * @return array
     */
    public function getAccountAliasesByDomainName($domain)
    {
        $accounts = $this->getByDomainName($domain);

        foreach($accounts as $account)
        {
            /* @var $account Account */
            foreach($account->getAliases() as $al)
            {

                $alias = new AccountAlias();
                $alias->setAccountId($account->getId());
                $alias->setAccountName($account->getName());
                $alias->setAlias($al);
                $data[] = $alias;
            }

        }
        return $data;
    }

}