<?php
/* * ********************************************************************
*  ProxmoxVPS Product developed. (27.03.19)
* *
*
*  CREATED BY MODULESGARDEN       ->       http://modulesgarden.com
*  CONTACT                        ->       contact@modulesgarden.com
*
*
* This software is furnished under a license and may be used and copied
* only  in  accordance  with  the  terms  of such  license and with the
* inclusion of the above copyright notice.  This software  or any other
* copies thereof may not be provided or otherwise made available to any
* other person.  No title to and  ownership of the  software is  hereby
* transferred.
*
*
* ******************************************************************** */

namespace ModulesGarden\Servers\ProxmoxCloudVps\App\UI\VirtualInterface\Providers;

use MGProvision\Proxmox\v2\Api;
use MGProvision\Proxmox\v2\models\Kvm;
use MGProvision\Proxmox\v2\ProxmoxApiException;
use ModulesGarden\ProxmoxAddon\App\Models\VirtualInterface;
use ModulesGarden\ProxmoxAddon\App\Models\VirtualNetwork;
use ModulesGarden\ProxmoxAddon\App\Models\VmIpAddress;
use ModulesGarden\ProxmoxAddon\App\Services\ApiService;
use ModulesGarden\ProxmoxAddon\App\Services\Cloud\IpSetIpFilterService;
use ModulesGarden\ProxmoxAddon\App\Services\Cloud\NetworkService;
use ModulesGarden\ProxmoxAddon\App\Services\Cloud\ProductService;
use ModulesGarden\ProxmoxAddon\App\Services\Cloud\VirtualInterfaceConverter;
use ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Interfaces\ClientArea;
use ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\ResponseTemplates\HtmlDataJsonResponse;
use ModulesGarden\Servers\ProxmoxCloudVps\Core\UI\Widget\Forms\DataProviders\BaseModelDataProvider;
use function ModulesGarden\Servers\ProxmoxCloudVps\Core\Helper\sl;
use Illuminate\Database\Capsule\Manager as DB;

class VirtualInterfaceProvider extends BaseModelDataProvider implements ClientArea
{
    use ProductService;
    use ApiService;

    /**
     * @var NetworkService
     */
    private $networkService;

    /**
     * VmUpdateProvider constructor.
     */
    public function __construct()
    {
        $this->model = new VirtualInterface();
        $this->networkService = new NetworkService();
    }

    public function read()
    {
        $this->availableValues['vn_id']['public'] = sl('lang')->abtr('Public');
        foreach (VirtualNetwork::ofHostingId($this->getWhmcsParamByKey('serviceid'))->select('id', 'name')->get() as $vn) {
            $this->availableValues['vn_id'][$vn->id] = $vn->name;
        }
        if ($this->getActionElementIdValue()) {
            $this->data['id'] = $this->getActionElementIdValue();
        }
    }

    public function create()
    {

        $this->model->fill($this->getFormDataValues());
        $this->model->hosting_id = $this->getWhmcsParamByKey('serviceid');
        $this->model->vm_id = \ModulesGarden\ProxmoxAddon\Core\Helper\sl('Vm')->getVmModel()->id;
        $this->model->ip_long = ip2long($this->model->ip);
        $virtualNetworkId = $this->getRequestValue('formData')['vn_id'];
        $this->model->vn_id = $virtualNetworkId == "public" ? 0 : $virtualNetworkId;
        try {
            DB::beginTransaction();
            Api::beginTransaction();
            if($virtualNetworkId == "public" ){
                VmIpAddress::ofHostingId($this->getWhmcsParamByKey('serviceid'))
                    ->ofIp($this->model->ip)
                    ->update(['vm_id' => $this->model->vm_id]);
            }
            $this->model->save();
            $vm = \ModulesGarden\ProxmoxAddon\Core\Helper\sl('Vm')->getVm();
            $conveter = new VirtualInterfaceConverter([$this->model], $vm);
            if($vm instanceof Kvm && $vm->isRunning()){
                $conveter->convert();
                $cdrom = $vm->getCdRomRepository();
                if($cdrom->hasCloudInit() ){
                    $cloudInitDrive = $cdrom->getCloudInitDrive();
                }
                try {
                    $vm->updateConfig($conveter->getNetworkDevicesAsConfig());
                    $vm->updateConfig($conveter->getIpConfigsAsConfig());
                    //Regenerate image
                    if($cloudInitDrive ){
                        $cloudInitDrive->unmount();
                        $cloudInitDrive->mount();
                    }
                }catch (ProxmoxApiException $ex) {
                    if(preg_match("/hotplug problem/", $ex->getMessage())){
                        $vm->updateConfig($conveter->getIpConfigsAsConfig());
                        //Regenerate image
                        if($cloudInitDrive ){
                            $cloudInitDrive->unmount();
                            $cloudInitDrive->mount();
                        }
                    }else{
                        throw $ex;
                    }
                }
            }else{
                //Update container
                $vm->updateConfig($conveter->asConfig());
            }
            DB::commit();
            if ($this->configuration()->isIpsetIpFilter()){
                $ipSetFilterService =  new IpSetIpFilterService();
                $ipSetFilterService->create();
            }
        } catch (\Exception $ex) {
            DB::rollBack();
            Api::commit();
            throw $ex;
        }
        return (new HtmlDataJsonResponse())
            ->setStatusSuccess()
            ->setMessageAndTranslate('The Virtual interface has been created successfully')
            ->addData('createButtonStatus', false)
            ->addRefreshTargetId('virtualInterfaceDataTable')
            ->addRefreshTargetId('networkDataTable')
            ->setCallBackFunction('pmToggleButton');
    }


    public function update()
    {

    }

    public function delete()
    {
        $vi = $this->model->where('id', $this->getFormDataValues()['id'])
            ->ofHostingId($this->getWhmcsParamByKey('serviceid'))
            ->firstOrFail();
        $this->networkService->deleteByIpAddresses([$vi]);
        if ($this->configuration()->isIpsetIpFilter()){
            $ipSetFilterService =  new IpSetIpFilterService();
            $ipSetFilterService->create();
        }
        return (new HtmlDataJsonResponse())
            ->setStatusSuccess()
            ->setMessageAndTranslate('The Virtual :name: network has been deleted successfully')
            ->addData('createButtonStatus', true)
            ->addRefreshTargetId('virtualInterfaceDataTable')
            ->addRefreshTargetId('networkDataTable')
            ->setCallBackFunction('pmToggleButton');

    }


}