<?php

namespace App\Classes\MikrotikService;

use App\Classes\MikrotikService\MikrotikStaticIPLogic\ArpProtocol;
use RouterOS\Query;
use App\Classes\MikrotikService\MikrotikStaticIPLogic\FirewallFilter;
use App\Classes\MikrotikService\MikrotikStaticIPLogic\QueueStaticIP;

class MikrotikStaticIP extends MikrotikConfig
{
    use FirewallFilter;
    use QueueStaticIP;
    use ArpProtocol;

    public function __construct(string $host, string $user, string $pass, int $port = 8728)
    {
        parent::__construct($host,  $user,  $pass,  $port);
    }

    public function getInterfaces($interfaceName = null)
    {
        $interfaceQuery = new Query("/ip/address/print");
        if ($interfaceName) {
            $interfaceQuery->where("interface", $interfaceName);
        }

        $interfaceResponse = $this->client->query($interfaceQuery)->read();

        return $interfaceName ? $interfaceResponse[0] : $interfaceResponse;
    }





    public function createStaticIP($ipConfig)
    {

        $existingQueue = $this->getQueues("target", $ipConfig['ip_address']);

        if (array_key_exists('mac_address', $ipConfig)) {
            $existingArp = $this->getArpList($ipConfig['ip_address']);
            $macAddress = filter_var($ipConfig['mac_address'], FILTER_VALIDATE_MAC);
            $arpData = [
                "interface" => $ipConfig['interface'],
                "address" => $ipConfig['ip_address'],
                "disabled" => $ipConfig['action'] == "accept" ? "no" : "yes",
            ];

            if ($macAddress) {
                $arpData["mac-address"] = $ipConfig['mac_address'];
            }

            if ($existingArp && $existingArp["dynamic"] == "false") {
                $this->updateArp($ipConfig['ip_address'], $arpData);
            } else if ($macAddress) {
                $this->createArp($arpData);
            }
        }



        if ($existingQueue) {
            $this->updateQueue($ipConfig['ip_address'], [
                "name" => $ipConfig['ip_address'],
                "target" => $ipConfig['ip_address'],
                "max-limit" => $ipConfig['max-limit'],
                "limit-at" => $ipConfig['max-limit'],
                "disabled" => $ipConfig['action'] == "accept" ? "no" : "yes",
                "comment" => $ipConfig["comment"]
            ]);
        } else {
            $this->createQueue([
                "name" => $ipConfig['ip_address'],
                "target" => $ipConfig['ip_address'],
                "max-limit" => $ipConfig['max-limit'],
                "limit-at" => $ipConfig['max-limit'],
                "disabled" => $ipConfig['action'] == "accept" ? "no" : "yes",
                "comment" => $ipConfig["comment"]
            ]);
        }
    }

    public function updateStaticIP($static_ip, $ipConfig)
    {

        $queryFirewallFilterArr = [
            "chain" => "forward",
        ];

        if (array_key_exists('action', $ipConfig)) {
            $queryFirewallFilterArr["action"] = $ipConfig['action'];
        }
        if (array_key_exists('ip_address', $ipConfig)) {
            $queryFirewallFilterArr["src-address"] = $ipConfig['ip_address'];
        }


        $queueQueryArr = [];

        if (array_key_exists('ip_address', $ipConfig)) {
            $queueQueryArr["name"] = $ipConfig["ip_address"];
            $queueQueryArr["target"] = $ipConfig["ip_address"];
        }

        if (array_key_exists('max-limit', $ipConfig)) {
            $queueQueryArr["max-limit"] = $ipConfig['max-limit'];
            $queueQueryArr["limit-at"] = $ipConfig['max-limit'];
        }

        if (array_key_exists('action', $ipConfig)) {
            $queueQueryArr["disabled"] =  $ipConfig['action'] == "accept" ? "no" : "yes";
        }
        if (!$this->getQueues("target", $static_ip)) {
            return $this->createQueue($queueQueryArr);
        }

        $this->updateQueue($static_ip,  $queueQueryArr);
    }

    public function disableStaticIP($static_ip)
    {

        if ($this->getQueues($static_ip)) {
            $this->updateQueue($static_ip, [
                "disabled" => "yes"
            ]);
        }

        if ($this->getArpList($static_ip)) {
            $this->updateArp($static_ip, [
                "disabled" => "yes"
            ]);
        }
    }

    public function enableStaticIP($static_ip)
    {
        if ($this->getQueues($static_ip)) {
            $this->updateQueue($static_ip, [
                "disabled" => "no"
            ]);
        }

        if ($this->getArpList($static_ip)) {
            $this->updateArp($static_ip, [
                "disabled" => "no"
            ]);
        }
    }
}
