<?php

namespace MGModule\DNSManager2\mgLibs\custom\dns;

use MGModule\DNSManager2\mgLibs\custom\SubmoduleCap;
use MGModule\DNSManager2\mgLibs\custom\TaskManager;
use MGModule\DNSManager2\models\custom\zone\Repository;

class Strategy
{
    const PRE   = 'pre';
    const AFTER = 'after';

    protected static $events = [
        'addRecord'     => [
            self::AFTER => 'RecordSynchronization:syncAdd'
        ],
        'deleteRecord'  => [
            self::AFTER => 'RecordSynchronization:syncDelete'
        ],
        'editRecord'    => [
            self::AFTER => 'RecordSynchronization:syncEdit'
        ],
        'activateZone'  => [
            self::AFTER => 'RecordSynchronization:syncActivateZone'
        ],
        'terminateZone' => [
            self::AFTER => 'RecordSynchronization:syncTerminateZone'
        ],
        'removeRDNS'    => [
            self::AFTER => 'RecordSynchronization:syncRemoveRDNS'
        ],
        'updateRDNS'    => [
            self::AFTER => 'RecordSynchronization:syncUpdateRDNS'
        ],
    ];

    protected $module;

    public function __construct($module)
    {
        $this->module = new SubmoduleCap($module);
    }

    public function __call($name, $args)
    {
        $result = call_user_func_array(array($this->module,$name), $args);
        //$result = count($args) == 1 ? $this->module->{$name}($args[0]) : $this->module->{$name}($args);
        if (isset(self::$events[$name][self::AFTER]))
        {
            $this->addTask($name, $args, self::AFTER);
        }
        return $result;
    }

    public function __get($name)
    {
        return $this->module->{$name};
    }

    public function getModule()
    {
        return $this->module;
    }

    private function addTask($name, $args, $when)
    {
        $packageServerRepo = new \MGModule\DNSManager2\models\custom\package\server\Repository();
        $packageServer = $packageServerRepo->byServerID($this->module->getServer()->id)->get()[0];
        if (!$packageServer || !$packageServer->isMaster())
        {
            return;
        }
        switch ($name)
        {
            case "deleteRecord":
            case "editRecord":
            case "addRecord":
                if (($this->taskExistsWithStatusStart('deleteRecord', self::AFTER)
                     || $this->taskExistsWithStatusStart('editRecord', self::AFTER)
                     || $this->taskExistsWithStatusStart('addRecord', self::AFTER)))
                {
                    return;
                }
                TaskManager::addTask(self::$events[$name][$when] . "_" . $this->module->getDomain(), ['submodule' => $this, 'values' => $args, 'zone' => $this->getZone()]);
                break;
            default:
                if (!$this->taskExistsWithStatusStart($name, $when))
                {
                    TaskManager::addTask(self::$events[$name][$when] . "_" . $this->module->getDomain(), ['submodule' => $this, 'values' => $args, 'zone' => $this->getZone()]);
                }
                break;
        }
    }

    private function getZone()
    {
        $zoneRepository = Repository::factory();
        return $zoneRepository->byServerID($this->getServer()->id)->byName($this->getDomain())->get()[0];
    }

    private function taskExistsWithStatusStart(string $name, string $when): bool
    {
        return count(TaskManager::getTasksByNameAndStatus(self::$events[$name][$when] . "_" . $this->module->getDomain(), 'start')) > 0;
    }

}