<?php

namespace ModulesGarden\ProxmoxAddon\App\Services\Cloud;

use MGProvision\Proxmox\v2\models\IpCidr;
use MGProvision\Proxmox\v2\models\IpSet;
use MGProvision\Proxmox\v2\repository\IpCidrRepository;
use MGProvision\Proxmox\v2\repository\IpSetRepository;
use ModulesGarden\ProxmoxAddon\App\Models\VirtualInterface;
use ModulesGarden\ProxmoxAddon\App\Models\VmIpAddress;
use ModulesGarden\ProxmoxAddon\App\Services\ApiService;
use ModulesGarden\ProxmoxAddon\Core\UI\Traits\WhmcsParams;
use function ModulesGarden\ProxmoxAddon\Core\Helper\sl;

class IpSetIpFilterService
{
    use WhmcsParams;
    use ApiService;
    use ProductService;

    public function create()
    {

        $networkDevices = sl('Vm')->getVm()->getNetworkDevices();
        if (count($networkDevices) <= 0)
        {
            return $this;
        }
        $ipCurrent = [];
        foreach ($networkDevices as $nd)
        {
            //Read
            $ipSetRep = new IpSetRepository();
            $ipSetRep->setApi($this->api());
            $path = sl('Vm')->getVm()->getPath() . "/" . IpSet::DEFAULT_PATH;
            $ipSetRep->findByPath($path);
            $ipSet = $ipSetRep->find((new IpSet)->setName('ipfilter-' . $nd->getId()));
            if (!$ipSet)
            {
                $ipSet = (new IpSet(sl('Vm')->getVm()->getPath() . "/" . IpSet::DEFAULT_PATH))
                    ->setApi($this->api())
                    ->setName('ipfilter-' . $nd->getId())
                    ->setComment('only allow specified IPs on ' . $nd->getId())
                    ->create();
            }
            //Add
            $query = VirtualInterface::ofHostingId($this->getWhmcsParamByKey("serviceid"))
                                      ->ofVmId(sl('Vm')->getVmModel()->id)
                                      ->ofNet($nd->getId());

            foreach ($query->get() as $ip)
            {
                /* @var VirtualInterface $ip */
                $ipCurrent[] = $ip->ip;
                $ipCirRep    = new IpCidrRepository();
                $ipCirRep->findByPath($ipSet->getPath());
                if ($ipCirRep->find((new IpCidr)->setCidr($ip->ip)))
                {
                    continue;
                }
                $ipCird = new IpCidr($ipSet->getPath());
                $ipCird->setApi($this->api());
                $ipCird->setCidr($ip->ip)->setComment($nd->getId())->create();
            }
        }
        unset($networkDevices, $ipSetRep, $ipSet, $ipCirRep);
        //Delete
        foreach (sl('Vm')->getVm()->getIpSet() as $ipSet)
        {
            $ipCidrs = $ipSet->getIpCidr();
            foreach ($ipCidrs as $key => $ipCidr)
            {
                if (in_array($ipCidr->getCidr(), $ipCurrent))
                {
                    continue;
                }
                $query = VirtualInterface::ofHostingId($this->getWhmcsParamByKey("serviceid"))
                    ->ofVmId(sl('Vm')->getVmModel()->id)
                    ->ofIp($ipCidr->getCidr());
                if ($query->count() < 1)
                {
                    $ipCidr->delete();
                    unset($ipCidrs[$key]);
                    if (count($ipCidrs) == 0)
                    {
                        $ipSet->delete();
                    }
                }
            }
        }
        return $this;
    }
}