<?php

namespace app\models\mikrotik\switchm;

use yii\base\Model;
use Yii;

require_once 'PEAR2_Net_RouterOS-1.0.0b5.phar';

use PEAR2\Net\RouterOS;
use app\models\mikrotik\MikrotikConnect;

class Rule extends Model {

    public $id;
    public $switch;
    public $ports;
    public $src_mac_address;
    public $dst_mac_address;
    public $mac_protocol;
    public $vlan_header;
    public $vlan_id;
    public $vlan_priority;
    public $src_address6;
    public $dst_address6;
    public $traffic_class;
    public $flow_label;
    public $copy_to_cpu;
    public $redirect_to_cpu;
    public $mirror;
    public $new_dst_ports;
    public $new_vlan_priority;
    public $invalid;
    public $disabled;
    public $src_address;
    public $dst_address;
    public $protocol;
    public $src_port;
    public $dst_port;
    public $dscp;
    public $new_vlan_id;

    public function rules() {
        return [
            ['id', 'string'],
            ['switch', 'string'],
            ['src_mac_address', 'string'],
            ['dst_mac_address', 'string'],
            ['mac_protocol', 'string'],
            ['vlan_header', 'string'],
            ['vlan_id', 'string'],
            ['vlan_priority', 'string'],
            ['src_address6', 'string'],
            ['dst_address6', 'string'],
            ['traffic_class', 'string'],
            ['flow_label', 'string'],
            ['copy_to_cpu', 'string'],
            ['redirect_to_cpu', 'string'],
            ['mirror', 'string'],
            ['new_vlan_priority', 'string'],
            ['invalid', 'string'],
            ['disabled', 'string'],
            ['src_address', 'string'],
            ['dst_address', 'string'],
            ['protocol', 'string'],
            ['src_port', 'string'],
            ['dscp', 'string'],
            ['new_vlan_id', 'string'],
        ];
    }

    public function getAll() {
        $connect = MikrotikConnect::Instance();
        $getRequest = new RouterOS\Request('/interface/ethernet/switch/rule/getall');
        $responses = $connect->getConnection()->sendSync($getRequest);
        $return = array();
        foreach ($responses as $response) {
            if ($response->getProperty('.id') != null) {
                $c = new Rule();
                $c->id = $response->getProperty('.id');
                $c->switch = $response->getProperty('switch');
                $c->ports = $response->getProperty('ports');
                $c->src_mac_address = $response->getProperty('src-mac-address');
                $c->dst_mac_address = $response->getProperty('dst-mac-address');
                $c->mac_protocol = $response->getProperty('mac-protocol');
                $c->vlan_header = $response->getProperty('vlan-header');
                $c->vlan_id = $response->getProperty('vlan-id');
                $c->vlan_priority = $response->getProperty('vlan-priority');
                $c->src_address6 = $response->getProperty('src-address6');
                $c->dst_address6 = $response->getProperty('dst-address6');
                $c->traffic_class = $response->getProperty('traffic-class');
                $c->flow_label = $response->getProperty('flow-label');
                $c->copy_to_cpu = $response->getProperty('copy-to-cpu');
                $c->redirect_to_cpu = $response->getProperty('redirect-to-cpu');
                $c->mirror = $response->getProperty('mirror');
                $c->new_dst_ports = $response->getProperty('new-dst-ports');
                $c->new_vlan_priority = $response->getProperty('new-vlan-priority');
                $c->invalid = $response->getProperty('invalid');
                $c->disabled = $response->getProperty('disabled');
                $c->src_address = $response->getProperty('src-address');
                $c->dst_address = $response->getProperty('dst-address');
                $c->protocol = $response->getProperty('protocol');
                $c->src_port = $response->getProperty('src-port');
                $c->dst_port = $response->getProperty('dst-port');
                $c->dscp = $response->getProperty('dscp');
                $c->new_vlan_id = $response->getProperty('new-vlan-id');
                $return[] = $c;
            }
        }
        return $return;
    }

    public function get($id) {
        $connect = MikrotikConnect::Instance();
        $getRequest = new RouterOS\Request('/interface/ethernet/switch/rule/print');
        $getRequest->setQuery(RouterOS\Query::where('.id', $id));
        $responses = $connect->getConnection()->sendSync($getRequest);
        foreach ($responses as $response) {
            if ($response->getProperty('.id') != null) {
                $this->id = $id;
                $this->switch = $response->getProperty('switch');
                $this->ports = $response->getProperty('ports');
                $this->src_mac_address = $response->getProperty('src-mac-address');
                $this->dst_mac_address = $response->getProperty('dst-mac-address');
                $this->mac_protocol = $response->getProperty('mac-protocol');
                $this->vlan_header = $response->getProperty('vlan-header');
                $this->vlan_id = $response->getProperty('vlan-id');
                $this->vlan_priority = $response->getProperty('vlan-priority');
                $this->src_address6 = $response->getProperty('src-address6');
                $this->dst_address6 = $response->getProperty('dst-address6');
                $this->traffic_class = $response->getProperty('traffic-class');
                $this->flow_label = $response->getProperty('flow-label');
                $this->copy_to_cpu = (($response->getProperty('copy-to-cpu') == 'true') ? true : false);
                $this->redirect_to_cpu = (($response->getProperty('redirect-to-cpu') == 'true') ? true : false);
                $this->mirror = (($response->getProperty('mirror') == 'true') ? true : false);
                $this->new_dst_ports = $response->getProperty('new-dst-ports');
                $this->new_vlan_priority = $response->getProperty('new-vlan-priority');
                $this->invalid = (($response->getProperty('invalid') == 'true') ? true : false);
                $this->disabled = (($response->getProperty('disabled') == 'true') ? true : false);
                $this->src_address = $response->getProperty('src-address');
                $this->dst_address = $response->getProperty('dst-address');
                $this->protocol = $response->getProperty('protocol');
                $this->src_port = $response->getProperty('src-port');
                $this->dst_port = $response->getProperty('dst-port');
                $this->dscp = $response->getProperty('dscp');
                $this->new_vlan_id = $response->getProperty('new-vlan-id');
            }
        }
        return;
    }

    public function update($id) {
        $c = new Rule();
        $c->get($id);
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/interface/ethernet/switch/rule/set');
        $setRequest->setargument('.id', $id);
        if ($this->switch != $c->switch) {
            $setRequest->setargument('switch', $this->switch);
        }
        if ($this->ports != $c->ports) {
            $setRequest->setargument('ports', $this->ports);
        }
        if ($this->src_mac_address != $c->src_mac_address) {
            if ($this->src_mac_address == '') {
                $unset[] = 'src-mac-address';
            } else {
                $setRequest->setargument('src-mac-address', $this->src_mac_address);
            }
        }
        if ($this->dst_mac_address != $c->dst_mac_address) {
            if ($this->dst_mac_address == '') {
                $unset[] = 'dst-mac-address';
            } else {
                $setRequest->setargument('dst-mac-address', $this->dst_mac_address);
            }
        }
        if ($this->mac_protocol != $c->mac_protocol) {
            if ($this->mac_protocol == '') {
                $unset[] = 'mac-protocol';
            } else {
                $setRequest->setargument('mac-protocol', $this->mac_protocol);
            }
        }
        if ($this->vlan_header != $c->vlan_header) {
            if ($this->vlan_header == '') {
                $unset[] = 'vlan-header';
            } else {
                $setRequest->setargument('vlan-header', $this->vlan_header);
            }
        }
        if ($this->vlan_id != $c->vlan_id) {
            if ($this->vlan_id == '') {
                $unset[] = 'vlan-id';
            } else {
                $setRequest->setargument('vlan-id', $this->vlan_id);
            }
        }
        if ($this->vlan_priority != $c->vlan_priority) {
            if ($this->vlan_priority == '') {
                $unset[] = 'vlan-priority';
            } else {
                $setRequest->setargument('vlan-priority', $this->vlan_priority);
            }
        }
        if ($this->src_address6 != $c->src_address6) {
            if ($this->src_address6 == '') {
                $unset[] = 'src-address6';
            } else {
                $setRequest->setargument('src-address6', $this->src_address6);
            }
        }
        if ($this->dst_address6 != $c->dst_address6) {
            if ($this->dst_address6 == '') {
                $unset[] = 'dst-address6';
            } else {
                $setRequest->setargument('dst-address6', $this->dst_address6);
            }
        }
        if ($this->traffic_class != $c->traffic_class) {
            if ($this->traffic_class == '') {
                $unset[] = 'traffic-class';
            } else {
                $setRequest->setargument('traffic-class', $this->traffic_class);
            }
        }
        if ($this->flow_label != $c->flow_label) {
            if ($this->flow_label == '') {
                $unset[] = 'flow-label';
            } else {
                $setRequest->setargument('flow-label', $this->flow_label);
            }
        }
        $setRequest->setargument('copy-to-cpu', (($this->copy_to_cpu == true) ? "true" : "false"));
        $setRequest->setargument('redirect-to-cpu', (($this->redirect_to_cpu == true) ? "true" : "false"));
        $setRequest->setargument('mirror', (($this->mirror == true) ? "true" : "false"));
        if ($this->new_dst_ports != $c->new_dst_ports) {
            if ($this->new_dst_ports == '') {
                $unset[] = 'new-dst-ports';
            } else {
                $setRequest->setargument('new-dst-ports', $this->new_dst_ports);
            }
        }
        if ($this->new_vlan_priority != $c->new_vlan_priority) {
            if ($this->new_vlan_priority == '') {
                $unset[] = 'new-vlan-priority';
            } else {
                $setRequest->setargument('new-vlan-priority', $this->new_vlan_priority);
            }
        }


        if ($this->src_address != $c->src_address) {
            if ($this->src_address == '') {
                $unset[] = 'src-address';
            } else {
                $setRequest->setargument('src-address', $this->src_address);
            }
        }
        if ($this->dst_address != $c->dst_address) {
            if ($this->dst_address == '') {
                $unset[] = 'dst-address';
            } else {
                $setRequest->setargument('dst-address', $this->dst_address);
            }
        }
        if ($this->protocol != $c->protocol) {
            if ($this->protocol == '') {
                $unset[] = 'protocol';
            } else {
                $setRequest->setargument('protocol', $this->protocol);
            }
        }
        if ($this->src_port != $c->src_port) {
            if ($this->src_port == '') {
                $unset[] = 'src-port';
            } else {
                $setRequest->setargument('src-port', $this->src_port);
            }
        }
        if ($this->dst_port != $c->dst_port) {
            if ($this->dst_port == '') {
                $unset[] = 'dst-port';
            } else {
                $setRequest->setargument('dst-port', $this->dst_port);
            }
        }
        if ($this->dscp != $c->dscp) {
            if ($this->dscp == '') {
                $unset[] = 'dscp';
            } else {
                $setRequest->setargument('dscp', $this->dscp);
            }
        }
        if ($this->new_vlan_id != $c->new_vlan_id) {
            if ($this->new_vlan_id == '') {
                $unset[] = 'new-vlan-id';
            } else {
                $setRequest->setargument('new-vlan-id', $this->new_vlan_id);
            }
        }
        if (isset($unset)) {
            $unsetRequest = new RouterOS\Request('/interface/ethernet/switch/rule/unset');
            foreach ($unset as $value) {
                $unsetRequest->setArgument('.id', $id);
                $unsetRequest->setArgument('value-name', $value);
                $resp = $connect->getConnection()->sendSync($unsetRequest);
                if ($resp->getType() !== RouterOS\Response::TYPE_FINAL) {
                    if (!isset($re)) {
                        $re = '';
                    } $re.= ' ' . $resp->getProperty('message');
                }
            }
        } $resp = $connect->getConnection()->sendSync($setRequest);
        if ($resp->getType() !== RouterOS\Response::TYPE_FINAL) {
            if (isset($re)) {
                $re.= ' ' . $resp->getProperty('message');
            } else {
                $re = $resp->getProperty('message');
            }
        } if (isset($re)) {
            return $re;
        } else {
            return '1';
        }
    }

    public function disable($id) {
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/interface/ethernet/switch/rule/disable');
        $setRequest->setArgument('.id', $id);
        $connect->getConnection()->sendSync($setRequest);
        return;
    }

    public function enable($id) {
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/interface/ethernet/switch/rule/enable');
        $setRequest->setArgument('.id', $id);
        $connect->getConnection()->sendSync($setRequest);
        return;
    }

    public function create() {
        $connect = MikrotikConnect::Instance();
        $setRequest = new RouterOS\Request('/interface/ethernet/switch/rule/add');
        if ($this->id != "") {
            $setRequest->setargument('.id', $this->id);
        }
        if ($this->switch != "") {
            $setRequest->setargument('switch', $this->switch);
        }
        if ($this->ports != "") {
            $setRequest->setargument('ports', $this->ports);
        }
        if ($this->src_mac_address != "") {
            $setRequest->setargument('src-mac-address', $this->src_mac_address);
        }
        if ($this->dst_mac_address != "") {
            $setRequest->setargument('dst-mac-address', $this->dst_mac_address);
        }
        if ($this->mac_protocol != "") {
            $setRequest->setargument('mac-protocol', $this->mac_protocol);
        }
        if ($this->vlan_header != "") {
            $setRequest->setargument('vlan-header', $this->vlan_header);
        }
        if ($this->vlan_id != "") {
            $setRequest->setargument('vlan-id', $this->vlan_id);
        }
        if ($this->vlan_priority != "") {
            $setRequest->setargument('vlan-priority', $this->vlan_priority);
        }
        if ($this->src_address6 != "") {
            $setRequest->setargument('src-address6', $this->src_address6);
        }
        if ($this->dst_address6 != "") {
            $setRequest->setargument('dst-address6', $this->dst_address6);
        }
        if ($this->traffic_class != "") {
            $setRequest->setargument('traffic-class', $this->traffic_class);
        }
        if ($this->flow_label != "") {
            $setRequest->setargument('flow-label', $this->flow_label);
        }
        if ($this->copy_to_cpu != "") {
            $setRequest->setargument('copy-to-cpu', (($this->copy_to_cpu == true) ? "true" : "false"));
        }
        if ($this->redirect_to_cpu != "") {
            $setRequest->setargument('redirect-to-cpu', (($this->redirect_to_cpu == true) ? "true" : "false"));
        }
        if ($this->mirror != "") {
            $setRequest->setargument('mirror', (($this->mirror == true) ? "true" : "false"));
        }
        if ($this->new_dst_ports != "") {
            $setRequest->setargument('new-dst-ports', $this->new_dst_ports);
        }
        if ($this->new_vlan_priority != "") {
            $setRequest->setargument('new-vlan-priority', $this->new_vlan_priority);
        }
        if ($this->invalid != "") {
            $setRequest->setargument('invalid', (($this->invalid == true) ? "true" : "false"));
        }
        if ($this->disabled != "") {
            $setRequest->setargument('disabled', (($this->disabled == true) ? "true" : "false"));
        }
        if ($this->src_address != "") {
            $setRequest->setargument('src-address', $this->src_address);
        }
        if ($this->dst_address != "") {
            $setRequest->setargument('dst-address', $this->dst_address);
        }
        if ($this->protocol != "") {
            $setRequest->setargument('protocol', $this->protocol);
        }
        if ($this->src_port != "") {
            $setRequest->setargument('src-port', $this->src_port);
        }
        if ($this->dst_port != "") {
            $setRequest->setargument('dst-port', $this->dst_port);
        }
        if ($this->dscp != "") {
            $setRequest->setargument('dscp', $this->dscp);
        }
        if ($this->new_vlan_id != "") {
            $setRequest->setargument('new-vlan-id', $this->new_vlan_id);
        }
        $resp = $connect->getConnection()->sendSync($setRequest);
        if ($resp->getType() !== RouterOS\Response::TYPE_FINAL) {
            return $resp->getProperty('message');
        } else {
            return '1';
        }
    }

    public function delete($id) {
        $connect = MikrotikConnect::Instance();
        $util = new RouterOS\Util($connect->getConnection());
        $util->setMenu('/interface/ethernet/switch/rule');
        $util->remove(RouterOS\Query::where('.id', $id));
        return;
    }

}
