<?php

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


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\Exceptions\ZimbraServiceException;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Enums\ApiErrorCodes;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Interfaces\ApiService;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Models\DistributionList;
use ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Models\Domain;

/**
 *
 * Created by PhpStorm.
 * User: Tomasz Bielecki ( tomasz.bi@modulesgarden.com )
 * Date: 10.10.19
 * Time: 14:41
 * Class DeleteDomain
 */
class DeleteDomain extends ApiService
{

    protected $domain;

    /**
     * @return bool
     */
    public function isValid()
    {
        if(!$this->formData['domain'])
        {
            $this->setError('Domain not found');
            return false;
        }

        return true;
    }

    /**
     * @return mixed|void
     */
    public function process()
    {
        $this->setDomainAsActiveIfRequired();
        $this->removeLists();
        $this->removeAccounts();
        $this->removeDomain();
        if ($this->getError())
        {
            return false;
        }

        return true;
    }

    protected function setDomainAsActiveIfRequired()
    {
        $domain = $this->getOrLoadDomain();
        $domain->setAttrs([
            Domain::ATTR_DOMAIN_STATUS => Zimbra::ACC_STATUS_ACTIVE,
            Domain::ATTR_MAIL_STATUS    => Zimbra::ENABLED,
        ]);

        $response = $this->api->domain->update($domain);

        return $this;
    }

    /**
     * remove distribution list
     *
     * @return bool
     */
    protected function removeLists()
    {
        /**
         * get lists
         */
        $lists = $this->api->repository()->lists->getAllDistributionListsByDomain($this->formData['domain']);

        /**
         * remove each list
         */
        foreach($lists as $list)
        {
            /* @var $list DistributionList */
            $result = $this->api->distributionList->delete($list);
            if($this->api->distributionList->getError())
            {
                $this->throwError($this->api->distributionList->getError());
            }
        }

        return true;
    }

    /**
     *
     * @return bool
     *
     */
    protected function removeAccounts()
    {
        /**
         * get accounts from Zimbra
         */
        $accounts = $this->api->repository()->accounts->getByDomainName($this->formData['domain']);
        /**
         * remove each account
         */
        foreach($accounts as $account)
        {
            $result = $this->api->account->delete($account);
            if($this->api->account->getError())
            {
                $this->throwError($this->api->account->getError());
            }
        }

        return true;
    }

    /**
     * remove domain from API
     *
     * @return bool
     */
    protected function removeDomain()
    {
        /**
         *
         * get domain from zimbra
         */
        $domain = $this->getOrLoadDomain();


        /**
         * remove domain
         */
        $result = $this->api->domain->delete($domain);

        if(!$result && ApiErrorCodes::DOMAIN_DOES_NOT_EXISTS !== $this->api->domain->getLastResult()->getLastErrorCode())
        {
            $this->setError($this->api->domain->getError());
            return false;
        }

        return true;
    }

    /**
     *
     * @return \ModulesGarden\Servers\ZimbraEmail\App\Libs\Zimbra\Components\Api\Soap\Models\Domain
     */
    protected function getOrLoadDomain()
    {
        if(!$this->domain)
        {
            $this->domain = $this->api->repository()->domains->getByName($this->formData['domain']);
        }

        if ($this->api->repository()->domains->getError())
        {
            $this->throwError($this->api->repository()->domains->getError());
        }

        return $this->domain;
    }


}