<?php


namespace ModulesGarden\ProxmoxAddon\App\Services\Cloud;

use MGProvision\Proxmox\v2\repository\BackupScheduleRepository;
use MGProvision\Proxmox\v2\repository\FileRepository;
use MGProvision\Proxmox\v2\repository\FirewallRulesRepository;
use MGProvision\Proxmox\v2\repository\HardDiskRepostiory;
use MGProvision\Proxmox\v2\repository\MountPointRepostiory;
use MGProvision\Proxmox\v2\repository\SnapshotRepository;
use ModulesGarden\ProxmoxAddon\App\Models\SnapshotJob;
use ModulesGarden\ProxmoxAddon\App\Services\ApiService;
use ModulesGarden\ProxmoxAddon\App\Services\CloudService;
use ModulesGarden\ProxmoxAddon\App\Services\Utility;
use ModulesGarden\ProxmoxAddon\Core\UI\Traits\WhmcsParams;
use ModulesGarden\ProxmoxAddon\App\Enum\Cloud\ConfigurableOption;
use function ModulesGarden\Servers\ProxmoxCloudVps\Core\Helper\sl;

/**
 * Class ResourceGuard
 * @package ModulesGarden\ProxmoxAddon\App\Services\Cloud
 * @todo
 */
class ResourceGuard
{
    use WhmcsParams;
    use ProductService;
    use ApiService;


    public function backupLimit()
    {
        $cloudSerice  = new CloudService();
        //Backup repository
        $backupRepository = new FileRepository();
        $backupRepository->setApi($this->api());
        $backupRepository->findBackupByVmModel($cloudSerice->getVmModelWithVmid())
                        ->findByStorages([$this->configuration()->getBackupStorage()]);
        //Files limit
        $maxFiles = $this->getWhmcsConfigOption(ConfigurableOption::BACKUPS_FILES,  $this->configuration()->getBackupMaxFiles()) ;
        if ($maxFiles != "-1"  && $this->configuration()->isBackupRouting())
        {
            $maxFiles++;
        }
        if ($maxFiles != "-1" && $backupRepository->count() >= $maxFiles)
        {
            throw new \Exception(sl("lang")->abtr("The maximum number of backup files has been exceeded. Please remove the old backup files."));
        }
        //Size limit
        $maxSize = $this->getWhmcsConfigOption(ConfigurableOption::BACKUPS_SIZE,  $this->configuration()->getBackupMaxSize()) ;
        $used    = $backupRepository->size();
        Utility::unitFormat($used, "bytes", "gb");
        if ($maxSize != "-1" && $used >= $maxSize)
        {
            throw new \Exception(sl("lang")->abtr("The maximum size set for a backup has been exceeded. Please remove the old backup files."));
        }
    }

    /**
     * @return bool
     * @todo
     */
    public function hasBackupLimit()
    {
        try
        {
            $this->backupLimit();
            return true;
        }
        catch (\Exception $ex)
        {

        }
        return false;
    }

    public function backupJobLimit()
    {
        $this->backupLimit();
        $cloudSerice  = new CloudService();
        //Backup repository
        $backupRepository = new BackupScheduleRepository();
        $backupRepository->setApi($this->api());
        $backupRepository->findByVmModel($cloudSerice->getVmModelWithVmid());
        //Files limit
        $maxFiles = $this->getWhmcsConfigOption(ConfigurableOption::BACKUPS_FILES,  $this->configuration()->getBackupMaxFiles()) ;
        if ($maxFiles != "-1" && $backupRepository->count() >= $maxFiles)
        {
            throw new \Exception(sl("lang")->tr("The maximum number of backup files has been exceeded. Please remove the old backup files."));
        }
    }

    public function hasBackupJobLimit()
    {
        try
        {
            $this->backupJobLimit();
            return true;
        }
        catch (\Exception $ex)
        {

        }
        return false;
    }

    public function snapshotLimit()
    {

        $cloudSerice  = new CloudService();
        $snapshotRepository = new SnapshotRepository();
        $snapshotRepository->setApi($this->api());
        $snapshotRepository->findByVmModel($cloudSerice->getVmModels());
        $snapshotRepository->ignoreCurrent(true);
        //Files limit
        $maxFiles = $this->getWhmcsConfigOption(ConfigurableOption::SNAPSHOTS, $this->configuration()->getSnapshotMaxFiles());
        if ($maxFiles != "-1" && $snapshotRepository->count() >= $maxFiles)
        {
            throw new \Exception(sl("lang")->tr("The maximum number of snapshots has been exceeded. Please remove the old snapshots."));
        }
    }

    public function hasSnapshotLimit()
    {
        try
        {
            $this->snapshotLimit();
            return true;
        }
        catch (\Exception $ex)
        {

        }
        return false;
    }

    /**
     * @return bool
     * @to do implement snapshot jobs
     */
    public function snapshotJobLimit()
    {
        $max = $this->getWhmcsConfigOption(ConfigurableOption::SNAPSHOT_JOBS, $this->configuration()->getSnapshotJobs());
        if($max == "-1"){
            return;
        }
        $query = SnapshotJob::ofHostingId($this->getWhmcsParamByKey("serviceid"));
        if ($max != "-1" && $query->count() >= $max)
        {
            throw new \Exception(sl("lang")->tr("The maximum number of snapshot jobs has been exceeded. Please remove the old snapshot jobs."));
        }
        return true;
    }

    public function hasSnapshotJobLimit()
    {
        try
        {
            $this->snapshotJobLimit();
            return true;
        }
        catch (\Exception $ex)
        {

        }
        return false;
    }

    public function firewallLimit($new=0)
    {
        $cloudSerice  = new CloudService();
        $repository    = new FirewallRulesRepository();
        $repository->setApi($this->api());
        $paths=[];
        $repository->findByVmModel($cloudSerice->getVmModelWithVmid());
        //Files limit
        $max = (int)$this->configuration()->getFirewallMaxRules();
        if ($max != "-1" && $repository->count()+$new > $max)
        {
            throw new \Exception(sl("lang")->tr("The maximum number of firewall rules has been exceeded. Please remove the old firewall rules."));
        }
    }

    public function hasfirewallLimit()
    {
        try
        {
            $this->firewallLimit();
            return true;
        }
        catch (\Exception $ex)
        {

        }
        return false;
    }

}