<?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\ProxmoxVps\App\UI\Firewall\Forms;

use ModulesGarden\ProxmoxAddon\App\Services\ApiService;
use ModulesGarden\ProxmoxAddon\App\Services\Vps\ProductService;
use ModulesGarden\Servers\ProxmoxVps\App\UI\Validators\PortValidator;
use ModulesGarden\Servers\ProxmoxVps\Core\FileReader\Reader\Json;
use ModulesGarden\Servers\ProxmoxVps\Core\ModuleConstants;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Interfaces\ClientArea;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\BaseForm;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\Fields\BaseField;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\Fields\Hidden;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\Fields\Select;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\Fields\Switcher;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\Fields\Text;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\Sections\HalfPageSection;
use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\Sections\RawSection;
use function ModulesGarden\Servers\ProxmoxVps\Core\Helper\sl;


class RuleForm extends BaseForm implements ClientArea
{
    use  ApiService;
    use ProductService;
    private $mainSection;
    private $topSection;
    private $leftSection;
    private $rightSection;
    private $bottomSection;
    private $sectionFields=[];

    protected function initSections()
    {
        //Main
        $this->mainSection = new RawSection('mainSection');
        $this->mainSection->setMainContainer($this->mainContainer);
        //Left
        $this->leftSection = new HalfPageSection('leftSection');
        $this->leftSection->setMainContainer($this->mainContainer);
        //Right
        $this->rightSection = new HalfPageSection('rightSection');
        $this->rightSection->setMainContainer($this->mainContainer);
        //Add Top
        $this->topSection = new RawSection('topSection');
        $this->topSection->setMainContainer($this->mainContainer);
        //add main
        $this->mainSection->addSection( $this->topSection )->addSection($this->leftSection)->addSection($this->rightSection);
        $this->addSection($this->mainSection);
        //Bottom
        $this->bottomSection = new RawSection('bottomSection');
        $this->bottomSection->setMainContainer($this->mainContainer);
        $this->addSection($this->bottomSection);
    }

    protected function initFields()
    {
        /*Left*/
        //enable
        $field = new Switcher('enable');
        $this->topSection->addField($field);
        //type
        $this->addFieldType();
        //action
        $this->addFieldAction();
        //iface
        $this->addFieldIface();
        //source
        $field = new Text('source');
        $this->addSectionField($field);
        //dest
        $field = new Text('dest');
        $this->addSectionField($field);
        /*Right*/
        //macro
        $this->addFieldMacro();
        //proto
        $this->addFieldProto();
        //sport
        $field = new Text('sport');
        $field->addValidator(new PortValidator());
        $this->addSectionField($field);
        //dport
        $field = new Text('dport');
        $field->addValidator(new PortValidator());
        $this->addSectionField($field);
        //comment
        $field = new Text('comment');
        $this->bottomSection->addField($field);
        $this->addFieldsToSections();
    }

    protected function addFieldPos()
    {
        $field = new Hidden('pos');
        $this->bottomSection->addField($field);
    }

    private function addFieldType()
    {
        $field = new Select('type');
        $field->setAvailableValues([
            "in"  => sl('lang')->tr("in"),
            "out" => sl('lang')->tr("out")
        ]);
        $this->addSectionField($field);
    }

    private function addFieldAction()
    {
        $field    = new Select('action');
        $enteries = new Json('actions.json', ModuleConstants::getFullPath('storage', 'app', "firewall"));
        $options  = [];
        foreach ($enteries->get() as $key => $v)
        {
            $options[$key] = sl('lang')->tr($v);
        }
        $field->setAvailableValues($options);
        $this->addSectionField($field);
    }

    private function addFieldIface()
    {
        $field      = new Select('iface');
        $ifaces     = [];
        $interfaces = $this->configuration()->getFirewallInterfaces();
        if (in_array("venet", $interfaces))
        {
            $ifaces["venet"] = sl('lang')->tr("venet");
        }
        if (in_array("eth", $interfaces))
        {
            foreach ($this->vm()->getNetworkDevices() as $nd)
            {
                $ifaces[$nd->getId()] = $nd->getId();
            }
        }
        $field->setAvailableValues($ifaces);
        $this->addSectionField($field);
    }

    private function addFieldMacro()
    {
        $field  = new Select('macro');
        $macros = ["0" => sl("lang")->tr("None")];
        foreach ($this->api()->get("/cluster/firewall/macros", []) as $response)
        {
            $macros[$response['macro']] = sl("lang")->tr($response['descr']);
        }
        $field->setAvailableValues($macros);
        $this->addSectionField($field);
    }

    private function addFieldProto()
    {
        $field    = new Select('proto');
        $enteries = new Json('protocols.json', ModuleConstants::getFullPath('storage', 'app', "firewall"));
        $options  = [];
        foreach ($enteries->get() as $key => $v)
        {
            $options[$key] = sl('lang')->tr($v);
        }
        $field->setAvailableValues($options);
        $this->addSectionField($field);
    }

    public function addSectionField(BaseField $field)
    {
        $this->sectionFields[] = $field;
        return $this;
    }

    private function addFieldsToSections(){
        foreach($this->sectionFields as $k => $field){
            if($k % 2 == 0 ){
                $this->leftSection->addField($field);
            }else{
                $this->rightSection->addField($field);
            }
        }
        unset($this->sectionFields);
    }


}