<?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',
                    'systemJobs',
                    'removeAll',
                    'delete',
                    'alerts',
                    'removeAllAlerts',
                    'deleteAlert',
                    'alertDescr',
                    'callProtectionImport',
                    'support'
                ),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('allow', // allow only if applianceMode is true
                'actions' => array(
                    'applianceCmd',
                    'restartProcess',
                    'rebootSystem',
                    'shutdownSystem',
                    'checkRestartStatus',
                    "getGaugeData"
                ),
                'expression' => (string) Yii::app()->params->applianceMode,
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    public function actionGetGaugeData()
    {
        $model = new SystemOverview();

        $gaugeData = array();
        if ($model->hasCPUThermalInfo()) {
            $gaugeData["cpuGaugeContainer"] = $model->getCPUTemperature();
        }
        if ($model->hasSystemLoadInfo(SystemLoadInfo::ONE_MINUTE)) {
            $gaugeData["loadOneMinGaugeContainer"] = $model->getSystemLoad(SystemLoadInfo::ONE_MINUTE);
        }
        if ($model->hasSystemLoadInfo(SystemLoadInfo::FIVE_MINUTES)) {
            $gaugeData["loadFiveMinGaugeContainer"] = $model->getSystemLoad(SystemLoadInfo::FIVE_MINUTES);
        }
        if ($model->hasSystemLoadInfo(SystemLoadInfo::TEN_MINUTES)) {
            $gaugeData["loadTenMinGaugeContainer"] = $model->getSystemLoad(SystemLoadInfo::TEN_MINUTES);
        }
        if ($model->hasRamInfo()) {
            $gaugeData["ramGaugeContainer"] = $model->getFormattedMemValue();
        }
        if ($model->hasHddInfo(MemoryInfo::MOUNT_POINT_ROOT)) {
            $gaugeData["rootGaugeContainer"] = $model->getFormattedMemValue(MemoryInfo::MOUNT_POINT_ROOT);
        }
        if ($model->hasHddInfo(MemoryInfo::MOUNT_POINT_DB)) {
            $gaugeData["dbGaugeContainer"] = $model->getFormattedMemValue(MemoryInfo::MOUNT_POINT_DB);
        }
        if ($model->hasHddInfo(MemoryInfo::MOUNT_POINT_SD_CARD)) {
            $gaugeData["sdcardGaugeContainer"] = $model->getFormattedMemValue(MemoryInfo::MOUNT_POINT_SD_CARD);
        }

        echo json_encode($gaugeData);
    }

    public function renderSystemLoadGauge($data)
    {
        $model = new SystemOverview();

        $html = "";
        if ($model->hasCPUThermalInfo()) {
            $cpuTemperatureGauge = GaugesFactory::getGaugeInstance("cpu", GaugesFactory::CPU_TEMPERATURE, $model);
            $cpuTemperatureGauge->setLabel(__("SYSTEM_OVERVIEW_GAUGE_LABEL_CPU_TEMPERATURE"));
            $html .= $this->renderPartial("animatedStatusGauge", $cpuTemperatureGauge->getGaugeOptions(), true, false);
        }
        if ($model->hasSystemLoadInfo(SystemLoadInfo::ONE_MINUTE)) {
            $oneMinLoadGauge = GaugesFactory::getGaugeInstance("loadOneMin", GaugesFactory::SYSTEM_LOAD, $model, SystemLoadInfo::ONE_MINUTE);
            $oneMinLoadGauge->setLabel(__("SYSTEM_OVERVIEW_GAUGE_LABEL_SYSTEM_LOAD_PER_ONE_MIN"));
            $html .= $this->renderPartial("animatedStatusGauge", $oneMinLoadGauge->getGaugeOptions(), true, false);
        }
        if ($model->hasSystemLoadInfo(SystemLoadInfo::FIVE_MINUTES)) {
            $fiveMinLoadGauge = GaugesFactory::getGaugeInstance("loadFiveMin", GaugesFactory::SYSTEM_LOAD, $model, SystemLoadInfo::FIVE_MINUTES);
            $fiveMinLoadGauge->setLabel(__("SYSTEM_OVERVIEW_GAUGE_LABEL_SYSTEM_LOAD_PER_FIVE_MINUTES"));
            $html .= $this->renderPartial("animatedStatusGauge", $fiveMinLoadGauge->getGaugeOptions(), true, false);
        }
        if ($model->hasSystemLoadInfo(SystemLoadInfo::TEN_MINUTES)) {
            $tenMinLoadGauge = GaugesFactory::getGaugeInstance("loadTenMin", GaugesFactory::SYSTEM_LOAD, $model, SystemLoadInfo::TEN_MINUTES);
            $tenMinLoadGauge->setLabel(__("SYSTEM_OVERVIEW_GAUGE_LABEL_SYSTEM_LOAD_PER_TEN_MINUTES"));
            $html .= $this->renderPartial("animatedStatusGauge", $tenMinLoadGauge->getGaugeOptions(), true, false);
        }

        return $html;
    }

    public function renderMemoryGauge($data)
    {

        $model = new SystemOverview();

        $html = "";
        if ($model->hasRamInfo()) {
            $ramMemoryGauge = GaugesFactory::getGaugeInstance("ram", GaugesFactory::RAM_MEMORY_USAGE, $model);
            $ramMemoryGauge->setLabel(__("SYSTEM_OVERVIEW_GAUGE_LABEL_MEMORY_USAGE_RAM"));
            $html .= $this->renderPartial("animatedStatusGauge", $ramMemoryGauge->getGaugeOptions(), true, false);
        }

        if ($model->hasHddInfo(MemoryInfo::MOUNT_POINT_ROOT)) {
            $driveMemoryGauge = GaugesFactory::getGaugeInstance("root", GaugesFactory::HDD_MEMORY_USAGE, $model, MemoryInfo::MOUNT_POINT_ROOT);
            $driveMemoryGauge->setLabel(__("SYSTEM_OVERVIEW_GAUGE_LABEL_MEMORY_USAGE_ROOT"));
            $html .= $this->renderPartial("animatedStatusGauge", $driveMemoryGauge->getGaugeOptions(), true, false);
        }

        if ($model->hasHddInfo(MemoryInfo::MOUNT_POINT_DB)) {
            $driveMemoryGauge = GaugesFactory::getGaugeInstance("db", GaugesFactory::HDD_MEMORY_USAGE, $model, MemoryInfo::MOUNT_POINT_DB);
            $driveMemoryGauge->setLabel(__("SYSTEM_OVERVIEW_GAUGE_LABEL_MEMORY_USAGE_DB"));
            $html .= $this->renderPartial("animatedStatusGauge", $driveMemoryGauge->getGaugeOptions(), true, false);
        }

        if ($model->hasHddInfo(MemoryInfo::MOUNT_POINT_SD_CARD)) {
            $driveMemoryGauge = GaugesFactory::getGaugeInstance("sdcard", GaugesFactory::HDD_MEMORY_USAGE, $model, MemoryInfo::MOUNT_POINT_SD_CARD);
            $driveMemoryGauge->setLabel(__("SYSTEM_OVERVIEW_GAUGE_LABEL_MEMORY_USAGE_SD_CARD"));
            $html .= $this->renderPartial("animatedStatusGauge", $driveMemoryGauge->getGaugeOptions(), true, false);
        }
        return $html;
    }

    /**
     * Lists all models.
     */
    public function actionIndex()
    {
        $model = new SystemOverview();
        $this->render('index', array('model' => $model));
    }

    public function renderTabMenu($grid)
    {
        $items = array_merge(array('---'), $this->getTabMenuItems($grid));
        return $this->renderPartial('_tabMenu', array('items' => $items));
    }

    protected function getTabMenuItems($grid)
    {
        $items = array(
            array(
                'name' => 'systemOverview',
                'label' => __('SYSTEMOVERVIEW_HEADER_TITLE'),
                'icon' => 'lightbulb',
                'url' => url('systemOverview'),
                'active' => $grid === 'systemOverview' ? true : false,
                'linkOptions' => array('data-translation-id' => 'SYSTEMOVERVIEW_HEADER_TITLE'),
            ),
            array(
                'name' => 'systemJob',
                'label' => __('SYSTEMJOB_HEADER_TITLE'),
                'icon' => 'rocket',
                'url' => url('systemOverview/default/systemJobs'),
                'active' => $grid === 'systemJob' ? true : false,
                'linkOptions' => array('data-translation-id' => 'SYSTEMJOB_HEADER_TITLE'),
            ),
            array(
                'name' => 'alerts',
                'label' => __('SYSTEMOVERVIEW_ALERTS_HEADER_TITLE'),
                'icon' => 'bolt',
                'url' => url('systemOverview/default/alerts'),
                'active' => $grid === 'alerts' ? true : false,
                'linkOptions' => array('data-translation-id' => 'SYSTEMOVERVIEW_ALERTS_HEADER_TITLE'),
            ),
        );

        if (Yii::app()->params->applianceMode) {
            $items = array_merge($items, array($this->getApplianceCmd($grid)));
        }
        return array_merge($items, array($this->getSupportButton($grid)));
    }

    protected function getApplianceCmd($grid)
    {
        return array(
            'name' => 'applianceCmd',
            'label' => __('SYSTEMOVERVIEW_APPLIANCE_CMD'),
            'icon' => 'cogs',
            'url' => url('systemOverview/default/applianceCmd'),
            'active' => $grid === 'applianceCmd' ? true : false,
            'linkOptions' => array('data-translation-id' => 'SYSTEMOVERVIEW_APPLIANCE_CMD'),
        );
    }

    protected function getSupportButton($grid)
    {
        return array(
            'name' => 'support',
            'label' => __('SYSTEMOVERVIEW_SUPPORT_BUTTON'),
            'icon' => 'h-sign',
            'url' => url('systemOverview/default/support'),
            'active' => $grid === 'support' ? true : false,
            'linkOptions' => array('data-translation-id' => 'SYSTEMOVERVIEW_SUPPORT_BUTTON'),
        );
    }

    public function renderSystemOverviewGridKeys($data)
    {
        $label = '';
        if (isset($data['descr'])) {
            $label = 'SYSTEM_OVERVIEW_' . strtoupper($data['descr']);
        }
        return '<b data-translation-id="' . $label . '">' . __($label) . '</b>';
    }

    public function renderSystemOverviewGridValue($data)
    {
        if ($data["descr"] === "current_system_time") {
            return $this->renderPartial("systemClock", $data, true, false);
        } else if ($data["descr"] === "call_protection") {
            $url = url('systemOverview/default/callProtectionImport');
            return $this->renderPartial("callProtectionImport", array('url' => $url, 'data' => $data["value"]), true, false);
        }

        $value = '';
        if (isset($data['value'])) {
            $value = $data['value'];
        }
        return $value;
    }

    public function renderStatisticsOverviewColumns($model)
    {
        $columns = array();
        $columns[] = array(
            'header' => __('SYSTEM_OVERVIEW_TITLE_STATISTICS_OVERVIEW'),
            'headerHtmlOptions' => array('data-translation-id' => 'SYSTEM_OVERVIEW_TITLE_STATISTICS_OVERVIEW'),
            'type' => 'raw',
            'value' => array($this, 'renderSystemOverviewGridKeys'),
        );

        foreach ($model->getDefaultStatisticsTemplate() as $key => $value) {
            if (is_int($key)) {
                $columns[] = (string) $key;
            }
        }
        return $columns;
    }

    public function actionSystemJobs()
    {
        $model = new Job('search');
        $model->unsetAttributes();  // clear any default values
        if (isset($_GET['Job'])) {
            $model->attributes = $_GET['Job'];
        }

        $this->render('systemJob', array(
            'model' => $model,
            'customButtons' => $this->getSystemJobCustomButtons(),
        ));
    }

    protected function getSystemJobCustomButtons()
    {
        $removeAll[] = array(
            'label' => __('SYSTEM_JOBS_REMOVE_JOBS'),
            'icon' => 'trash',
            'url' => url('systemOverview/default/removeAll'),
            'position' => 'right',
            'linkOptions' => array(
                'data-translation-target' => 'SYSTEM_JOBS_REMOVE_BUTTON',
                'confirm' => __('SYSTEM_JOBS_CONFIRM_REMOVE_JOBS')
            )
        );
        return array_merge($this->getTabMenuItems('systemJob'), $removeAll);
    }

    public function actionRemoveAll()
    {
        while ($models = Job::model()->findAll()) {
            foreach ($models as $model) {
                $model->delete();
            }
        }
        $this->redirect(url('systemOverview/default/systemJobs'));
    }

    public function actionDelete($id)
    {
        if (Yii::app()->request->isPostRequest) {
            // we only allow deletion via POST request
            $this->loadModel($id)->delete();

            // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
            if (!isset($_GET['ajax'])) {
                $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('index'));
            }
        } else {
            throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
        }
    }

    public function loadModel($id)
    {
        $model = Job::model()->findByPk($id);
        if ($model === null) {
            throw new CHttpException(404, 'The requested page does not exist.');
        }
        return $model;
    }

    public function renderStatus($data)
    {
        $this->renderPartial('gridStatusCell', array('data' => $data));
    }

    public function actionApplianceCmd()
    {
        try {
            PhonalisaCtrldConnector::getProcesses();
        } catch (Exception $exc) {
            Yii::app()->user->setErrorFlashMessage($exc->getMessage());
            $this->render('error');
        }

        $model = new SystemOverview();
        $this->render('applianceCmd', array('model' => $model));
    }

    public function renderProcessStatus($data)
    {
        $status = '';
        $type = '';
        if (isset($data['value']['status'])) {
            $status = SystemOverviewProcessStatus::getHumanReadableStatus($data['value']['status']);
            $type = SystemOverviewProcessStatus::getStatusColor($data['value']['status']);
        }
        return $this->renderPartial('processStatusCell', array('status' => $status, 'type' => $type));
    }

    public function renderRestartProcessButtons($data)
    {
        $label = 'SYSTEM_OVERVIEW_RESTART_PROCESS_BUTTON';
        $url = url('systemOverview/default/restartProcess');
        $process = '';
        $redirect = '';
        if (isset($data['descr'])) {
            $process = $data['descr'];
        }
        return $this->renderPartial('_restartButton', array(
                    'process' => $process,
                    'label' => $label,
                    'url' => $url,
                    'redirect' => $redirect
                        )
        );
    }

    public function renderProcessName($data)
    {
        if (isset($data['descr'])) {
            $data['descr'] = str_replace('-', '_', $data['descr']);
        }
        return $this->renderSystemOverviewGridKeys($data);
    }

    public function actionRestartProcess()
    {
        $process = @$_REQUEST['process'];
        if (!empty($process)) {
            $result = PhonalisaCtrldConnector::restartProcess($process);
            echo json_encode($result->status);
            Yii::app()->end();
        }
    }

    public function renderSystemShutdownRebootBtn($data)
    {
        $url = '#';
        $process = '';
        $redirect = '';
        if (isset($data['descr'])) {
            $process = $data['descr'];
        }

        if ($process === SystemOverviewProcesses::REBOOT) {
            $url = url('systemOverview/default/rebootSystem');
            $redirect = url('site/reboot', array('redirect' => 'systemOverview/default/applianceCmd'));
        } elseif ($process === SystemOverviewProcesses::SHUTDOWN) {
            $url = url('systemOverview/default/shutdownSystem');
            $redirect = url('site/shutdown');
        }

        $label = SystemOverviewProcesses::getHumanReadableProcess($process);
        return $this->renderPartial('_restartButton', array(
                    'process' => $process,
                    'label' => $label,
                    'url' => $url,
                    'redirect' => $redirect
                        )
        );
    }

    public function renderSystemShutdownRebootName($data)
    {
        if (isset($data['descr'])) {
            $data['descr'] = $data['descr'] . '_SYSTEM';
        }
        return $this->renderSystemOverviewGridKeys($data);
    }

    public function actionRebootSystem()
    {
        $process = @$_REQUEST['process'];
        if (!empty($process)) {
            $result = PhonalisaCtrldConnector::rebootSystem();
            echo json_encode($result->status);
            Yii::app()->end();
        }
    }

    public function actionShutdownSystem()
    {
        $process = @$_REQUEST['process'];
        if (!empty($process)) {
            $result = PhonalisaCtrldConnector::shutdownSystem();
            echo json_encode($result->status);
            Yii::app()->end();
        }
    }

    public function actionCheckRestartStatus()
    {
        $process = @$_REQUEST['process'];
        $status = '';
        if (isset($process)) {
            $status = (string) SystemOverview::model()->getProcessStatusByKey($process);
        }
        echo json_encode($status);
        Yii::app()->end();
    }

    public function actionAlerts()
    {
        $model = new Alert('search');
        $model->unsetAttributes();  // clear any default values

        $this->render('alert', array(
            'model' => $model,
            'customButtons' => $this->getAlertCustomButtons(),
        ));
    }

    protected function getAlertCustomButtons()
    {
        $removeAll[] = array(
            'label' => __('SYSTEM_OVERVIEW_REMOVE_ALERTS'),
            'icon' => 'trash',
            'url' => url('systemOverview/default/removeAllAlerts'),
            'position' => 'right',
            'linkOptions' => array(
                'data-translation-target' => 'SYSTEM_OVERVIEW_ALERTS_REMOVE_BUTTON',
                'confirm' => __('SYSTEM_OVERVIEW_CONFIRM_REMOVE_ALERTS')
            )
        );
        return array_merge($this->getTabMenuItems('alerts'), $removeAll);
    }

    public function actionRemoveAllAlerts()
    {
        while ($models = Alert::model()->findAll()) {
            foreach ($models as $model) {
                $model->delete();
            }
        }
        $this->redirect(url('systemOverview/default/alerts'));
    }

    public function actionDeleteAlert($id)
    {
        if (Yii::app()->request->isPostRequest) {
            // we only allow deletion via POST request
            $this->loadAlertModel($id)->delete();

            // if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
            if (!isset($_GET['ajax'])) {
                $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('index'));
            }
        } else {
            throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
        }
    }

    public function loadAlertModel($id)
    {
        $model = Alert::model()->findByPk($id);
        if ($model === null) {
            throw new CHttpException(404, 'The requested page does not exist.');
        }
        return $model;
    }

    public function actionAlertDescr()
    {
        $result = array('status' => 'error');
        $id = @$_REQUEST['id'];
        if (isset($id)) {
            $model = Alert::model()->findByPk($id);
            if ($model) {
                $result['status'] = 'ok';
                $result['descr'] = CHtml::encode($model->descr);
                $result['shortDescr'] = CHtml::encode($model->shortDescr);
            }
        }
        echo json_encode($result);
        Yii::app()->end();
    }

    public function renderLevel($data)
    {
        return $this->renderPartial('alertLevel', array('data' => $data));
    }

    public function renderDateTime($data)
    {
        $date = PhonalisaDate::userDateTime($data->created, true);
        return $date;
    }

    public function renderSystemLoadGaugeGrid($model)
    {
        if ($model->hasCPUThermalInfo() ||
                $model->hasSystemLoadInfo(SystemLoadInfo::ONE_MINUTE) ||
                $model->hasSystemLoadInfo(SystemLoadInfo::FIVE_MINUTES) ||
                $model->hasSystemLoadInfo(SystemLoadInfo::TEN_MINUTES)
        ) {
            $id = "load-grid";
            $dataProvider = $model->getCurrentSystemLoad();
            $header = 'SYSTEM_OVERVIEW_TITLE_CURRENT_LOAD';
            $valueCallback = "renderSystemLoadGauge";
            $translationIds = array();
            if (app()->user->translateMode) {
                $translationIds[] = "SYSTEM_OVERVIEW_GAUGE_LABEL_CPU_TEMPERATURE";
                $translationIds[] = "SYSTEM_OVERVIEW_GAUGE_LABEL_SYSTEM_LOAD_PER_ONE_MIN";
                $translationIds[] = "SYSTEM_OVERVIEW_GAUGE_LABEL_SYSTEM_LOAD_PER_FIVE_MINUTES";
                $translationIds[] = "SYSTEM_OVERVIEW_GAUGE_LABEL_SYSTEM_LOAD_PER_TEN_MINUTES";
            }

            return $this->renderGaugeGrid($id, $dataProvider, $valueCallback, $header, $translationIds);
        }
        return "";
    }

    public function renderMemoryGaugeGrid($model)
    {
        if ($model->hasRamInfo() || $model->hasHddInfo()) {
            $id = "memory-overview-grid";
            $dataProvider = $model->getCurrentSystemLoad();
            $valueCallback = "renderMemoryGauge";
            $header = "SYSTEM_OVERVIEW_TITLE_CURRENT_MEMORY";

            $translationIds = array();
            if (app()->user->translateMode) {
                $translationIds[] = "SYSTEM_OVERVIEW_GAUGE_LABEL_MEMORY_USAGE_RAM";
                $translationIds[] = "SYSTEM_OVERVIEW_GAUGE_LABEL_MEMORY_USAGE_ROOT";
                $translationIds[] = "SYSTEM_OVERVIEW_GAUGE_LABEL_MEMORY_USAGE_DB";
                $translationIds[] = "SYSTEM_OVERVIEW_GAUGE_LABEL_MEMORY_USAGE_SD_CARD";
            }

            return $this->renderGaugeGrid($id, $dataProvider, $valueCallback, $header, $translationIds);
        }
        return "";
    }

    private function renderGaugeGrid($id, $dataProvider, $valueCallback, $header, $translationIds = array())
    {
        return $this->renderPartial("gaugeGrid", array(
                    "id" => $id,
                    "dataProvider" => $dataProvider,
                    "header" => $header,
                    "valueCallback" => $valueCallback,
                    "translationIds" => $translationIds,
                        ), true //return = true
        );
    }

    private function renderLastImportDateTime($data)
    {
        $date = PhonalisaDate::userDateTime($data['value'], true);
        return $date;
    }

    public function actionCallProtectionImport()
    {
        $job = new Job();
        $job->type = Job::CallProtectionImport;
        $job->meta = array();
        $job->status = Job::Inserted;
        $job->save();

        $scorelistEntryStatus = ScoreListEntryStatus::model()->findByAttributes(array());
        if (!$scorelistEntryStatus) {
            $scorelistEntryStatus = new ScoreListEntryStatus();
        }
        $scorelistEntryStatus->status = 'runs';
        $scorelistEntryStatus->message = __('CALL_PROTECTION_IMPORT_RUNNING_TEXT');
        $scorelistEntryStatus->datetime = PhonalisaDate::newServerDate();
        $scorelistEntryStatus->save();
        Log::v('CallProtection import started.', 'SystemOverview');
    }

    public function renderUserImportDateTime($dateTime = '')
    {
        $result = $dateTime;
        if (!empty($dateTime)) {
            $result = PhonalisaDate::userDateTime($dateTime, true);
        }
        return $result;
    }

    public function actionSupport()
    {
        $fileName = "phonalisa_Support_" . date('Y-m-d_G-i-s') . ".txt";
        header('Content-type: text/txt');
        header("Content-disposition: attachment; filename=$fileName");
        header("Pragma: no-cache");
        header("Expires: 0");
        print(ModelToJsonConverter::getJsonEncodedData());
    }
}
