<?php
class WizardStepApplianceNetworkSettings extends WizardStep
{
    
    const PHONALISA_DOMAIN = 'phonalisa.lan';
    
    private $networkInterface;
    
    protected function run()
    {
        
        $defaultNetworkInterface = NetworkInterface::model()->findByAttributes(array());
        
        $this->setNetworkInterface();
        
        /*
        if (!$defaultNetworkInterface) {
            $defaultNetworkInterface = new NetworkInterface();
        }
        */
        
        $defaultIp = $this->networkInterface->ip;
        
        $formModel = new ApplianceNetworkSettingsForm();
        $formModel->ip = $this->networkInterface->ip;
        $formModel->subnetMask = $this->networkInterface->netmask;
        $formModel->dns = $this->networkInterface->dns;
        $formModel->gateway = $this->networkInterface->gateway;
        
        
        $this->performAjaxValidation($formModel, "network-settings-form");
        if (isset($_POST["ApplianceNetworkSettingsForm"])) {
            $formModel->attributes = $_POST["ApplianceNetworkSettingsForm"];
            if ($formModel->validate()) {
                
                
                
                if ($this->changeNetworkInterfaceSettings($formModel)) {
                    NetworkInterface::writeNetworkConfigsToCtrld();
                } else {
                    return;
                }
                
                $this->setSystenConfigurations($formModel, $this->networkInterface);
                
                if ($formModel->enableDNSServer) {
                    if ($this->configureDNSServer($formModel)) {
                        $this->writeDnsConfig();
                    } else {
                        return;
                    }
                }
                
                if ($formModel->enableDHCP) {
                    if ($this->configureDHCP($formModel)) 
                    {
                        NetworkSettings::writeDhcpConfigsToCtrld();
                    } else {
                        return;
                    }
                }
                if ($defaultIp != $formModel->ip) {
                    $wizardModel = WizardHelper::getWizardModel();
                    $wizardModel->incrementStep();
                    $this->showNewPhonalisaLink($formModel->ip);
                    $this->rebootPhonalisa();
                    return;
                } else {
                    $this->setStepIsDone(true);
                    return;
                }
            }
        }
        
        $this->wizardController->render("applianceNetworkSettings", array("formModel" => $formModel));
    }
    
    private function setNetworkInterface() {
        $networkInterface = $this->networkInterface = NetworkInterface::model()->findByAttributes(array());
        if (!$networkInterface) {
            app()->user->setErrorFlashMessage('WIZARD_NO_NETWORK_INTERFACE_FOUND');
            return false;
        }
        $this->networkInterface = $networkInterface;
    }
    
    private function setSystenConfigurations($formModel, $networkInterface)
    {
        setCfg('PROV_HOST', $formModel->ip);
        setCfg('SIP_HOST', $formModel->ip);
        setCfg('NTP_HOST', $formModel->ip);
        
        setCfg('PROV_PORT', $this->getProvPort());
        setCfg('PROV_PORT_SECURE', $this->getProvPort(true));
        setCfg('PROV_INIT_FROM_NET', $networkInterface->getIpAsCIDR());
    }
    
    private function getProvPort($secure = false)
    {
        $port = $secure ? '443' : '80';
        
        $globalConfigDefault = Yii::app()->params->globalConfigDefault;
        if (!is_array($globalConfigDefault)) {
            return $port;
        }
        
        $settingsKey = $secure ? "PROV_PORT_SECURE" : "PROV_PORT";
        if (array_key_exists($settingsKey, $globalConfigDefault)) {
            $port = $globalConfigDefault[$settingsKey];
        }
        return $port;
    }
    
    private function changeNetworkInterfaceSettings($model)
    {
        $this->networkInterface->ip = $model->ip;
        $this->networkInterface->isPrimary = '1';
        $this->networkInterface->dns = $model->dns;
        $this->networkInterface->gateway = $model->gateway;
        $this->networkInterface->scenario = 'wizard';
        if (!$this->networkInterface->save()) {
            app()->user->setErrorFlashMessage('CHANGES_NOT_SAVED_CAUSE_OF_AN_ERROR', $this->networkInterface->getFormatedErrors());
            return false;
        }

        return true;
    }
    
    private function configureDNSServer($model)
    {
        
        $dnsModel = DNSServer::model()->findByAttributes(array('position' => '0'));
        if (!$dnsModel) {
            $dnsModel = new DNSServer();
        }
        
        
        $dnsModel->enableDNSServer = $model->enableDNSServer;
        $dnsModel->upstreamDNSServer = $model->dns;
        $dnsModel->position = 0;
        if (!$dnsModel->save()) {
            return false;
        }
        
        $dnsZone = DNSZone::model()->findByAttributes(array('position' => '0'));
        if (!$dnsZone) {
            $dnsZone = new DNSZone();
        }
        $dnsZone->fqdn = self::PHONALISA_DOMAIN;
        $dnsZone->position = 0;
        if (!$dnsZone->save()) {
            return false;
        }
        return true;
    }
    
    private function writeDnsConfig()
    { 
        $data = DNSServer::getDnsDataForCtrld();
        $ctrld = PhonalisaCtrldConnector::writeDnsConfig($data);

        $ctrldStatus = @$ctrld->status;
        $ctrldErrorTxt = @$ctrld->errorText;

        if (empty($ctrldStatus)) {
            app()->user->setErrorFlashMessage('GLOBAL_WRITE_TO_CTRLD_ERROR');
            return false;
        } else if ($ctrldStatus == 'error' && !empty($ctrldErrorTxt)) {
            app()->user->setErrorFlashMessage($ctrldErrorTxt);
            return false;
        }
        return true;
    }
    
    private function configureDHCP($model)
    {
        if (!PhonalisaCtrldConnector::hasConnection()) {
            app()->user->setErrorFlashMessage('NETWORK_SETTINGS_WRITE_TO_CTRLD_ERROR');
            return false;
        }

        $settings = array();
        $settings['ENABLE_DCHPD'] = $model->enableDHCP;
        $settings['GLOBAL_SUBNET_MASK'] = $this->networkInterface->netmask;
        $settings['GLOBAL_SUBNET'] = $this->networkInterface->getIpAsCIDR();
        $settings['GLOBAL_BROADCAST_ADDRESS'] = $this->networkInterface->getBroadcast();
        $settings['GLOBAL_ROUTER'] = $this->networkInterface->gateway;
        $settings['GLOBAL_DNS'] = $this->networkInterface->dns;
        $settings['GLOBAL_NTP'] = cfg('NTP_HOST');
        $settings['RANGE_FROM'] = $model->dhcpRangeFrom;
        $settings['RANGE_TO'] = $model->dhcpRangeTo;

        foreach ($settings as $key => $value) {
            if (!$this->saveNetworkSettings($key, $value)) {
                return false;
            }
        }
        return true;
    }
    
    private function saveNetworkSettings($key, $value)
    {
        $model = NetworkSettings::model()->findByAttributes(array('key' => $key));
        if (!$model) {
            $model = new NetworkSettings();
        }
        $model->key = $key;
        $model->value = $value;
        if (!$model->save()) {
            app()->user->setErrorFlashMessage('CHANGES_NOT_SAVED_CAUSE_OF_AN_ERROR', $model->getFormatedErrors());
            return false;
        }
        return true;
    }
    
    private function showNewPhonalisaLink($ip)
    {
        $protocol = 'http';
        if (app()->getRequest()->isSecureConnection) {
            $protocol = 'https';
        }
        $port = Yii::app()->getRequest()->serverPort;
        $url = $protocol . '://' . $ip . ':' . $port;
        $this->wizardController->render('wizard_phonalisaLink', array('url' => $url));
    }
    
    private function rebootPhonalisa()
    {
        PhonalisaCtrldConnector::rebootSystem();
    }
}

