<?php

namespace ThurData\Servers\KerioEmail\App\Libs\Metrics;

use WHMCS\UsageBilling\Contracts\Metrics\MetricInterface;
use WHMCS\UsageBilling\Contracts\Metrics\ProviderInterface;
use WHMCS\UsageBilling\Metrics\Metric;
use WHMCS\UsageBilling\Metrics\Usage;
use WHMCS\UsageBilling\Metrics\Units\GigaBytes;
use ThurData\Servers\KerioEmail\Api\KerioWhmcs;

class MyMetricProvider implements ProviderInterface
{
    private $moduleParams = [];
    public function __construct($moduleParams)
    {
        $this->moduleParams = $moduleParams;
    }

    public function metrics()
    {
        return [
            new Metric(
                'mailboxes',
                'Email Accounts',
                MetricInterface::TYPE_SNAPSHOT
            ),
            new Metric(
                'aliases',
                'Email Aliases',
                MetricInterface::TYPE_SNAPSHOT
            ),
            new Metric(
                'distributionLists',
                'Distribution Lists',
                MetricInterface::TYPE_SNAPSHOT
            ),
            new Metric(
                'domainAliases',
                'Domain Aliases',
                MetricInterface::TYPE_SNAPSHOT
            ),
            new Metric(
                'storage',
                'Storage',
                MetricInterface::TYPE_SNAPSHOT,
                new GigaBytes()
            )
        ];
    }

    public function usage()
    {
        $api = new KerioWhmcs('whmcsKerioEmail', 'Thurdata', '1.0');
        try {
            $api->login($this->moduleParams['serverhostname'], $this->moduleParams['serverusername'], $this->moduleParams['serverpassword']);
            $domains = $api->getDomains(['id','name','aliasList']);
        } catch (KerioApiException $error) {
            logModuleCall(
                'kerioEmail',
                __FUNCTION__,
                $error,
                'Debug Error',
                $error->getMessage()
            );
            return ['error' => $error->getMessage()];
        }
        $usage = [];

        foreach ($domains as $domain)
        {
            $domainName = $domain['name'];
            $domainID = $domain['id'];
            $countOfDomainAliases = count($domain['aliasList']);
            try
            {
                $fields = array(
					'loginName',
					'fullName',
					'consumedSize'
                );
                $mailboxes = $api->getUsers($fields,$domainID);
                $countOfMailboxes = count($mailboxes);
                $totalUsage = 0;
                if ($countOfMailboxes > 0) {
                    foreach ($mailboxes as $mailboxe) {
                        switch($mailboxe['consumedSize']['units']) {
                            case 'Bytes' :
                                $usage = $mailboxe['consumedSize']['value']/1024/1024;
                                break;
                            case 'KiloBytes' :
                                $usage = $mailboxe['consumedSize']['value']/1024;
                                break;
                            case 'MegaBytes' :
                                $usage = $mailboxe['consumedSize']['value'];
                                break;
                            case 'GigaBytes' :
                                $usage = $mailboxe['consumedSize']['value']*1024;
                                break;
                        }
                        $totalUsage += $usage;
                    }
                }
               $storage = $totalUsage == 0 ? 0 : round($totalUsage);
            } catch (KerioApiException $error) {
                logModuleCall(
                    'kerioEmail',
                    __FUNCTION__,
                    $error,
                    'Debug Error',
                    $error->getMessage()
                );
                return ['error' => $error->getMessage()];
            }
            try
            {
                $fields = array(
                    "id",
                    "name");
                $mailingLists = $api->getMailingLists($fields,$domainID);
                $countOfDistributionList = count($mailingLists);
            } catch (KerioApiException $error) {
                logModuleCall(
                    'kerioEmail',
                    __FUNCTION__,
                    $error,
                    'Debug Error',
                    $error->getMessage()
                );
                return ['error' => $error->getMessage()];
            }
            try
            {
                $fields = array(
                    "id",
                    "name");
                $aliases = $api->getAliases($fields,$domainID);
                $countOfEmailAliases = count($aliases);
            } catch (KerioApiException $error) {
                logModuleCall(
                    'kerioEmail',
                    __FUNCTION__,
                    $error,
                    'Debug Error',
                    $error->getMessage()
                );
                return ['error' => $error->getMessage()];
            }

            $domainData = [
                'mailboxes' => $countOfMailboxes,
                'distributionLists' => $countOfDistributionList,
                'aliases' => $countOfEmailAliases,
                'domainAliases' => $countOfDomainAliases,
                'storage' => $storage,
            ];

            $usage[$domainName] = $this->wrapUserData($domainData);

        }
        $api->logout();
        return $usage;
    }

    public function tenantUsage($tenant)
    {
        $api = new KerioWhmcs('whmcsKerioEmail', 'Thurdata', '1.0');
        try {
            $api->login($this->moduleParams['serverhostname'], $this->moduleParams['serverusername'], $this->moduleParams['serverpassword']);
            $domainID = $api->getDomainId($tenant);
        } catch (KerioApiException $error) {
            logModuleCall(
                'kerioEmail',
                __FUNCTION__,
                $error,
                'Debug Error',
                $error->getMessage()
            );
            return ['error' => $error->getMessage()];
        }
        $usage = [];
        $countOfDomainAliases = 0;
        if($domain['aliasList']){
            $countOfDomainAliases = count($domain['aliasList']);
        }
        try
        {
            $fields = array(
                'loginName',
                'fullName',
                'consumedSize'
            );
            $mailboxes = $api->getUsers($fields,$domainID);
            $countOfMailboxes = count($mailboxes);
            $totalUsage = 0;
            if ($countOfMailboxes > 0) {
                foreach ($mailboxes as $mailboxe) {
                    switch($mailboxe['consumedSize']['units']) {
                        case 'Bytes' :
                            $usage = $mailboxe['consumedSize']['value']/1024/1024;
                            break;
                        case 'KiloBytes' :
                            $usage = $mailboxe['consumedSize']['value']/1024;
                            break;
                        case 'MegaBytes' :
                            $usage = $mailboxe['consumedSize']['value'];
                            break;
                        case 'GigaBytes' :
                            $usage = $mailboxe['consumedSize']['value']*1024;
                            break;
                    }
                    $totalUsage += $usage;
                }
            }
            $storage = $totalUsage == 0 ? 0 : round($totalUsage);
        } catch (KerioApiException $error) {
            logModuleCall(
                'kerioEmail',
                __FUNCTION__,
                $error,
                'Debug Error',
                $error->getMessage()
            );
            return ['error' => $error->getMessage()];
        }
        try
        {
            $fields = array(
                "id",
                "name");
            $mailingLists = $api->getMailingLists($fields,$domainID);
            $countOfDistributionList = count($mailingLists);
        } catch (KerioApiException $error) {
            logModuleCall(
                'kerioEmail',
                __FUNCTION__,
                $error,
                'Debug Error',
                $error->getMessage()
            );
            return ['error' => $error->getMessage()];
        }
        try
        {
            $fields = array(
                "id",
                "name");
            $aliases = $api->getAliases($fields,$domainID);
            $countOfEmailAliases = count($aliases);
        } catch (KerioApiException $error) {
            logModuleCall(
                'kerioEmail',
                __FUNCTION__,
                $error,
                'Debug Error',
                $error->getMessage()
            );
            return ['error' => $error->getMessage()];
        }

        $domainData = [
            'mailboxes' => $countOfMailboxes,
            'distributionLists' => $countOfDistributionList,
            'aliases' => $countOfEmailAliases,
            'domainAliases' => $countOfDomainAliases,
            'storage' => $storage,
        ];

        $usage = $this->wrapUserData($domainData);

        $api->logout();
        return $usage;
    }

    private function wrapUserData($data)
    {
        $wrapped = [];
        foreach ($this->metrics() as $metric) {
            $key = $metric->systemName();
            if ($data[$key]) {
                $value = $data[$key];
                $metric = $metric->withUsage(
                    new Usage($value)
                );
            }

            $wrapped[] = $metric;
        }

        return $wrapped;
    }

}
