<?php

class DefaultController extends Controller
{

    /**
     * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
     * using two-column layout. See 'protected/views/layouts/column2.php'.
     */
    public $layout = '//layouts/column2';

    /**
     * @return array action filters
     */
    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
        );
    }

    /**
     * Specifies the access control rules.
     * This method is used by the 'accessControl' filter.
     * @return array access control rules
     */
    public function accessRules()
    {
        return array(
            array('allow', // allow all users to perform 'index' and 'view' actions
                'actions' => array(
                    'index',
                    'checkForUpdates',
                    'updateSystem',
                    'upgradeStatus',
                    'getStatusOutput',
                    'rebootSystem'
                ),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    /**
     * Lists all models.
     */
    public function actionIndex()
    {
        $model = new SystemUpdate();
        $dataProvider = $model->getSystemUpdateOverview();
        $installedVersionDP = $model->getInstalledVersionOverview();

        $systemNeedUpdate = $this->systemNeedUpdate();
        $this->render('index', array(
            'model' => $model,
            'dataProvider' => $dataProvider,
            'systemNeedUpdate' => $systemNeedUpdate,
            'installedVersionDP' => $installedVersionDP
        ));
    }

    public function actionCheckForUpdates()
    {
        $data = SystemUpdate::getUpdateFileDataFromServer();

        if (!empty($data)) {
            $sort = 0;
            foreach ($data as $key => $value) {
                $this->saveSystemUpdate($key, $value, $sort);
                $sort++;
            }
            $this->saveSystemUpdate('timestamp', PhonalisaDate::newServerTimestamp(), $sort++);
        } else {
            app()->user->setErrorFlashMessage('CTRLD: ' . __('SYSTEM_UPDATE_CANT_FIND_UPDATE_FILE'));
            Log::e("Can't find update.json", 'SystemUpdate');
        }
        $this->redirect(url('systemUpdate'));
    }

    protected function saveSystemUpdate($key, $value, $sort)
    {
        $model = SystemUpdate::model()->findByAttributes(array('descr' => $key));

        if (!$model) {
            $model = new SystemUpdate();
        }
        $model->descr = $key;
        $model->value = $value;
        $model->sort = $sort;
        if (!$model->save()) {
            app()->user->setErrorFlashMessage('CHANGES_NOT_SAVED_CAUSE_OF_AN_ERROR', $model->getFormatedErrors());
        }
    }

    public function renderDescr($data)
    {
        return $data->getAttributeLabel($data->descr);
    }

    public function renderInstalledGridDescr($data)
    {
        return SystemUpdate::model()->getAttributeLabel($data['descr']);
    }

    public function renderInstalledGridValue($data)
    {
        $value = $data['value'];
        if ($data['descr'] === 'timestamp') {
            if ($value != '') {
                $value = $this->getFormatedTimestamp($value, 'U');
            }
            $value.=$this->getLinkButton();
        }
        return $value;
    }

    public function renderValue($data)
    {
        $value = $data->value;
        if ($data->descr === 'releaseNotes') {
            $value = $this->getReleaseNotes($value);
        } else if ($data->descr === 'releaseDatetime') {
            $value = $this->getFormatedTimestamp($value, PhonalisaDate::ServertimePatternWithSeconds);
        }
        return $value;
    }

    protected function getReleaseNotes($value)
    {
        $parsedown = new Parsedown();
        $txt = base64_decode($value);
        return $parsedown->text($txt);
    }

    protected function getFormatedTimestamp($datetime, $format)
    {
        if ($format == 'U') {
            $format = PhonalisaDate::ServertimePatternWithSeconds;
            $datetime = PhonalisaDate::convertServerDateTo($format, PhonalisaDate::newServerDate((int) $datetime, "U"), false);
        }
        return PhonalisaDate::userDateTime(PhonalisaDate::convertServerDateTo($format, $datetime), true);
    }

    protected function getLinkButton()
    {
        return CHtml::linkButton(__('SYSTEM_UPDATE_SEARCH_FOR_UPDATES'), array(
                    'class' => 'modalSaveBtn btn btn-primary',
                    'href' => url('systemUpdate/default/checkForUpdates'),
                    'data-translation-id' => 'SYSTEM_UPDATE_SEARCH_FOR_UPDATES',
                    'style' => 'margin-left: 15px;'
                        )
        );
    }

    public function actionUpdateSystem()
    {
        $result = array(
            'status' => 'error',
            'statusMsg' => array(__('GLOBAL_COULD_NOT_CONNECT_TO_CTRLD'))
        );
        if (PhonalisaCtrldConnector::hasConnection()) {
            $ctrld = PhonalisaCtrldConnector::runSystemUpgrade();
            if (isset($ctrld->status)) {
                if ($ctrld->status === 'error') {
                    $result['statusMsg'] = @$ctrld->errorText;
                } else {
                    $result['status'] = 'ok';
                    unset($result['statusMsg']);
                }
            } else {
                $result['statusMsg'] = __('GLOBAL_CTRLD_CALL_TO_UNKNOWN_FUNCTION_ERROR');
            }
        }
        $this->writeMsgToFlash($result);

        echo json_encode($result);
        Yii::app()->end();
    }

    public function actionUpgradeStatus()
    {
        $this->layout = '//layouts/statusScreen';
        $this->render('statusScreen');
    }

    public function actionGetStatusOutput()
    {
        $result = PhonalisaCtrldConnector::getSystemUpgradeStatus();
        if (isset($result->status) && $result->status === 'ok') {
            SystemUpdate::createUpdateDoneAlert();
        }
        echo json_encode(@$result);
        Yii::app()->end();
    }

    protected function systemNeedUpdate()
    {
        $result = array(
            'status' => 'error',
            'statusMsg' => array(__('GLOBAL_COULD_NOT_CONNECT_TO_CTRLD'))
        );
        if (PhonalisaCtrldConnector::hasConnection()) {
            $ctrld = PhonalisaCtrldConnector::getSystemVersion();
            $result = $this->getSystemVersionErrorMsg($ctrld, $result);
        }

        $status = false;
        $this->writeMsgToFlash($result);
        if ($result['status'] === 'info') {
            $status = true;
        }
        return $status;
    }

    protected function getSystemVersionErrorMsg($ctrld, $result)
    {
        if (isset($ctrld->status) && isset($ctrld->version)) {
            if ($ctrld->status === 'error') {
                $result['statusMsg'] = @$ctrld->errorText;
            } else {
                if (SystemUpdate::serverVersionNewerThanSystem($ctrld->version)) {
                    $result['status'] = 'info';
                    $result['statusMsg'] = __('SYSTEM_UPDATE_PHONALISA_NEED_UPDATE');
                } else {
                    $result['status'] = 'ok';
                    $result['statusMsg'] = __('SYSTEM_UPDATE_PHONALISA_NEED_NO_UPDATE');
                }
            }
        } else {
            $result['statusMsg'] = __('GLOBAL_CTRLD_CALL_TO_UNKNOWN_FUNCTION_ERROR');
        }
        return $result;
    }

    protected function writeMsgToFlash($result)
    {
        if (!app()->user->getFlashes(false)) {
            if ($result['status'] === 'error') {
                app()->user->setErrorFlashMessage('CTRLD: ' . @$result['statusMsg']);
            } else if ($result['status'] === 'info') {
                app()->user->setFlash('info', '<strong>' . @$result['statusMsg'] . '</strong>');
            } else {
                app()->user->setSuccessFlashMessage(@$result['statusMsg']);
            }
        }
    }

    public function actionRebootSystem()
    {
        $result = array(
            'status' => 'error',
            'statusMsg' => array(__('GLOBAL_COULD_NOT_CONNECT_TO_CTRLD'))
        );

        if (PhonalisaCtrldConnector::hasConnection()) {
            $ctrld = PhonalisaCtrldConnector::rebootSystem();
            if (isset($ctrld->status) && $ctrld->status == 'ok') {
                $this->redirect(url('site/reboot'));
            } else {
                $result['statusMsg'] = @$ctrld->errorText;
                $this->writeMsgToFlash($result);
                $this->redirect(url('systemUpdate'));
            }
        }
    }
}
