<?php

class AlertController extends Controller {

    protected function beforeAction($event) {
        set_time_limit(TIME_MINUTE * 5);
        // access_denied_check("view_alerts");
        return parent::beforeAction($event);
    }

    public function filters() {
        return array(
            'postOnly + update',
            array(
                'application.filters.SyslogFilter - summary'
            )
        );
    }

    const RSS_AUTH_OPEN = "open";
    const RSS_AUTH_APIKEY = "apikey";
    const RSS_AUTH_BASIC = "basic";
    const RSS_AUTH_LOGIN = "login";

    public function actionRss() {
        /** @var Alert[] $alerts */
        $auth_type = paramdeep('alerts', 'rss', 'auth', 'type');
        $auth_type = paramdeep('alerts', 'rss', 'auth', 'type');

        switch ($auth_type) {
            case self::RSS_AUTH_OPEN :
                // ok
                break;
            case self::RSS_AUTH_APIKEY :
                // check apikey
                if (!User::model()->exists('apikey=:ak', array(
                            ':ak' => array_get($_REQUEST, 'apikey')
                        )))
                    access_denied_check(null, true, "Api key not found");
                break;
            case self::RSS_AUTH_BASIC :
                access_basic_check(array_get($_REQUEST, 'username'), array_get($_REQUEST, 'password'));
                break;
            case self::RSS_AUTH_LOGIN :
                access_denied_check('alert_rss');
                break;
            default :
                exit();
        }

        $count = paramdeep('alerts', 'rss', 'size');
        $version = paramdeep('alerts', 'rss', 'version');
        $link_logo = paramdeep('logos', 'login');
        if (isEmptyOrWhitespace($link_logo))
            $link_logo = null;
        else
            $link_logo = absoluteUrl("/images/{$link_logo}");
        $link_site = absoluteUrl('/');
        $link_feed = absoluteUrl('alert/rss');

        $alerts = Alert::model()->last($count)
                ->findAll();

        $feed = new EFeed($version);

        $feed->title = 'Event Server Alerts';
        $feed->link = $link_site;
        $feed->description = 'Event Server alerts RSS feed';
        $feed->RSS1ChannelAbout = $link_site;
        if ($link_logo != null)
            $feed->setImage($feed->title, $link_feed, $link_logo);

        $feed->addChannelTag('language', 'en-us');
        $feed->addChannelTag('pubDate', date(DATE_RSS, time()));
        $feed->addChannelTag('updated', date(DATE_ATOM, time()));
        $feed->addChannelTag('author', array(
            'name' => 'Event Server'
        ));
        $feed->addChannelTag('link', $link_feed);
        // $feed->addChannelTag ( 'atom:link', absoluteUrl ( 'alert/rss' ) . '/' );

        foreach ($alerts as $alert) {
            $item = $feed->createNewItem();

            $item->title = $alert->description;
            $item->link = absoluteUrl("alert/view", array(
                'id' => $alert->id
            ));
            $item->description = "{$alert->description} {$alert->event_note}";

            $item->date = time();

            // $item->setEncloser ( 'http://www.tester.com', '1283629', 'audio/mpeg' );
            // $item->addTag ( 'author', 'thisisnot@myemail.com (Antonio Ramirez)' );
            // $item->addTag ( 'guid', 'http://www.ramirezcobos.com/', array ( 'isPermaLink' => 'true' ) );
            // $item->addTag ( 'dc:subject', 'Subject Testing' );

            $feed->addItem($item);
        }

        $feed->generateFeed();
    }

    public function actionIndex(array $types = null, $bookmarkedOnly = null, array $gates = null) {
        $criteria = new CDbCriteria ();
        $criteria->order = 't.epoch DESC';

        $withCriteria = array(
            'takenInChargeOperator',
            'managedByOperator'
        );

        if (isset($bookmarkedOnly) && $bookmarkedOnly == true)
            $withCriteria [] = 'bookmark';

        $criteria->with = $withCriteria;
        $criteria->together = true;

        if ($types != null) {
            if (!is_array($types))
                $types = array(
                    $types
                );
            $criteria->addInCondition("t.type", $types);
        }

        if ($gates != null) {
            if (!is_array($gates))
                $types = array(
                    $gates
                );
            $criteria->addInCondition("t.gate", $gates);
        }

        $dataProvider = new CActiveDataProvider('Alert', array(
            'criteria' => $criteria,
            'pagination' => array(
                'pageSize' => 20
            )
        ));

        $gateList = Gate::getAllGates();

        if (Yii::app()->request->isAjaxRequest)
            $this->renderPartial('_alertsTable', array(
                'dataProvider' => $dataProvider
            ));
        else
            $this->render('index', array(
                'dataProvider' => $dataProvider,
                'types' => $types,
                'bookmark' => $bookmarkedOnly,
                'gateList' => $gateList,
                'selectedGates' => $gates
            ));
    }

    public function actionSearch(array $types = null, array $gates = null) {
        $model = new AlertSearchForm ();

        if (isset($types) || isset($gates)) {
            if (isset($types))
                $model->types = $types;

            if ($gates)
                $model->gates = $gates;
        }
        else if (isset($_GET ['AlertSearchForm'])) {
            // $model->attributes = $_GET['AlertSearchForm'];
            $model->setAttributes($_POST ['AlertSearchForm'], false);
        } else if (isset($_POST ['AlertSearchForm'])) {
            $model->setAttributes($_POST ['AlertSearchForm'], false);
        }

        $alert = new Alert ();

        if (!empty($model->description))
            $alert->byDescription($model->description);

        if (!empty($model->gates))
            $alert->byGate($model->gates);

        if (!empty($model->types))
            $alert->byType($model->types);

        if (isset($model->bookmark) && $model->bookmark > 0)
            $alert->withBookmark();

        if (isset($model->takenInChargeBy) && $model->takenInChargeBy > 0)
            $alert->takenInChargeBy(Yii::app()->user->model);

        if (isset($model->closedBy) && $model->closedBy > 0)
            $alert->managedBy(Yii::app()->user->model);

        if (!empty($model->startDateTime)) {
            $theStartTime = DateTime::createFromFormat(Yii::app()->params ['datetimeselect_format'] [Yii::app()->language] ['php'], $model->startDateTime);
            $alert->after($theStartTime);
        }

        if (!empty($model->endDateTime)) {
            $theEndTime = DateTime::createFromFormat(Yii::app()->params ['datetimeselect_format'] [Yii::app()->language] ['php'], $model->endDateTime);
            $alert->before($theEndTime);
        }

        $alert->youngerToOlder();

        $doExport = array_get($_REQUEST, 'btn_export') == "ok";

        $dataProvider = $alert->searchAlerts(!$doExport);

        if ($doExport) {
            set_time_limit(0);
            $nowDateTime = new DateTime ();
            $exportId = $nowDateTime->format("Y_m_d_H_i_s");
            $filename = "Alerts_" . $exportId . ".csv";
            $command = queryFromCriteriaCommand(Alert::model()->getTableSchema(), $dataProvider->criteria);
            $reader = $command->query();

            $exportObj = new stdClass ();
            $exportObj->rowIndex = 0;

            outputCsvFromReader($filename, $reader, function ($inputRow, $exportObj) {
                $row = array();
                if ($exportObj->rowIndex <= 0) {
                    $row [] = t('Description');
                    $row [] = t('Gate');
                    $row [] = t('Date');
                    $row [] = t('Time');
                    $row [] = t('Km/h');
                    $row [] = t('Kemler');
                    $row [] = t('Class');
                    $row [] = t('Nationality');
                    $row [] = t('Plate');
                    $row [] = t('Url');
                } else {
                    $a = new Alert ();
                    $a->setAttributes($inputRow, false);

                    $alert = new AlertPresenter($a);
                    $ve = $a->getAssociatedEvent();

                    if ($alert->event_note)
                        $row [] = t($alert->description) . " - " . $alert->event_note;
                    else
                        $row [] = t($alert->description);
                    $row [] = $alert->gateLabel;
                    $row [] = DateHelper::formatLocalDate($alert->alertDateTime);
                    $row [] = DateHelper::formatISO9075Time($alert->alertDateTime);
                    $row [] = $alert->vehicleSpeed;
                    $row [] = $alert->vehicleKemler;
                    $row [] = t($ve->getVehicleClass());
                    $row [] = $alert->nationalityCode;
                    $row [] = $alert->plate;
                    $row [] = absoluteUrl('alert/view', array(
                        'id' => $a->id
                    ));
                }
                $exportObj->rowIndex ++;

                return $row;
            }, $exportObj);

            exit();
        }
        $gateList = Gate::getAllGates();

        $this->render('search', array(
            'model' => $model,
            'dataProvider' => $dataProvider,
            'gateList' => $gateList
        ));
    }

    public function actionView($id) {
        // $this->layout = '//layouts/pdf'; // solo per debug
        $alert = $this->loadModel($id);
        $event = $alert->associatedEvent;
        if (isset($event)) {
            $klass = get_class($event);
            $actionName = "action{$klass}view";
            $this->$actionName($alert, $event);
        }
    }

    public function actionExportPdf($id) {
        access_denied_check('export_pdf');

        $alert = $this->loadModel($id);
        $event = $alert->associatedEvent;
        if (isset($event)) {
            $klass = get_class($event);
            $actionName = "doExportPdf{$klass}";
            $this->$actionName($id, $event->ID);
        }
    }

    private function doExportPdfVehicleTrace($alertId, $eventId) {
        $alert = $this->loadModel($alertId);
        $event = $this->findModel("VehicleTrace", $eventId);
        $operator = Yii::app()->user->model;

        $this->layout = '//layouts/pdf';
        $htmlPreview = $this->render('viewVehicleTracePdf', array(
            'alert' => $alert,
            'event' => $event,
            'editEnable' => false/* $alert->canEdit($operator->id) */
            , 'useLocalResources' => false
                ), true);
        $htmlData = $this->render('viewVehicleTracePdf', array(
            'alert' => $alert,
            'event' => $event,
            'editEnable' => false/* $alert->canEdit($operator->id) */
            , 'useLocalResources' => true
                ), true);

        $fileTitle = t('Alert') . "_" . $alertId;

        $fileTitle = str_replace(' ', '_', $fileTitle);

        if (true) {
            $varPreview = TempDataBuffer::instance()->add($htmlPreview);
            $varData = TempDataBuffer::instance()->add($htmlData);

            $this->redirect(array(
                'pdfExport/ExportPdf',
                'htmlVarPreview' => $varPreview,
                'htmlVarData' => $varData,
                'title' => $fileTitle
            ));
        } else {
            echo $html;
            exit();
        }
    }

    public function actionExportPdfEvent($id) {
        $event = $this->findModel("Event", $id);
        /** @var Event $event */
        $alert = $event->alert;
        /** @var Alert $alert */
        $alertId = ($alert != null) ? $alert->id : 0;
        $this->doExportPdfEvent($alertId, $id);
    }

    private function doExportPdfEvent($alertId, $eventId) {
        /** @var Alert $alert */
        /** @var Event $event */
        $alert = $this->loadModel($alertId, false);
        $event = $this->findModel("Event", $eventId);
        $operator = Yii::app()->user->model;

        $this->layout = '//layouts/pdf';
        $htmlPreview = $this->render('viewEventPdf', array(
            'alert' => $alert,
            'event' => $event,
            'useLocalResources' => false,
            'editEnable' => false/* $alert->canEdit($operator->id) */), true);
        $htmlData = $this->render('viewEventPdf', array(
            'alert' => $alert,
            'event' => $event,
            'useLocalResources' => true,
            'editEnable' => false/* $alert->canEdit($operator->id) */), true);

        if ($alert != null)
            $fileTitle = t('Alert') . "_" . $alertId;
        else
            $fileTitle = t('Event') . "_" . $eventId;

        $fileTitle = str_replace(' ', '_', $fileTitle);

        if (true) {
            $varPreview = TempDataBuffer::instance()->add($htmlPreview);
            $varData = TempDataBuffer::instance()->add($htmlData);

            $this->redirect(array(
                'pdfExport/ExportPdf',
                'htmlVarPreview' => $varPreview,
                'htmlVarData' => $varData,
                'title' => $fileTitle
            ));
        } else {
            echo $html;
            exit();
        }
    }

    private function doExportPdfNullEvent($alertId, $eventId) {
        $alert = $this->loadModel($alertId);
        $operator = Yii::app()->user->model;

        $this->layout = '//layouts/pdf';
        $html = $this->render('viewNullEventPdf', array(
            'alert' => $alert,
            'editEnable' => false/* $alert->canEdit($operator->id) */), true);

        $fileTitle = t('Alert') . "_" . $alertId;

        $fileTitle = str_replace(' ', '_', $fileTitle);

        if (true) {
            $varPreview = TempDataBuffer::instance()->add($html);
            $varData = TempDataBuffer::instance()->add($html);

            $this->redirect(array(
                'pdfExport/ExportPdf',
                'htmlVar' => 'htmlPdf',
                'title' => $fileTitle
            ));
        } else {
            echo $html;
            exit();
        }
    }

    public function actionVehicleTraceView($alert, $event) {

        $vars = $this->varsForWLSmartTips($event, $event->gate->Gate, $event->StartTime, $event->custom_nationality, $event->Plate);

        $operator = Yii::app()->user->model;
        $this->render('viewVehicleTrace', array(
            'alert' => $alert,
            'event' => $event,
            'editEnable' => $alert->canEdit($operator->id),
            'varsForWL' => $vars
        ));
    }

    public function actionNullEventView($alert, $event) {
        
        $vars = $this->varsForWLSmartTips($event, $event->gate->Gate, $event->StartTime, $event->custom_nationality, $event->Plate);
        $operator = Yii::app()->user->model;
        $this->render('viewGenericAlert', array(
            'alert' => $alert,
            'editEnable' => $alert->canEdit($operator->id),
            'varsForWL' => $vars
        ));
    }

    public function actionVehicleTraceUpdate($alert, $event, $params) {
        $event->attributes = $params;
        if ($event->save())
            Yii::app()->user->setFlash('success', t('Alert saved successfully'));
        else
            Yii::app()->user->setFlash('error', t('Errors. Please, check the form for more information before continue.'));

        $this->actionVehicleTraceView($alert, $event);
    }

    public function actionEventView($alert, $event) {
        $vars = $this->varsForWLSmartTips($event, $event->gate->Gate, $event->StartTime, $event->custom_nationality, $event->Plate);
        $operator = Yii::app()->user->model;
        $this->render('viewEvent', array(
            'alert' => $alert,
            'event' => $event,
            'editEnable' => $alert->canEdit($operator->id),
            'varsForWL' => $vars
        ));
    }

    public function actionEventUpdate($alert, $event, $params) {
        $event->attributes = $params;
        if ($event->save())
            Yii::app()->user->setFlash('success', t('Alert saved successfully'));
        else
            Yii::app()->user->setFlash('error', t('Errors. Please, check the form for more information before continue.'));

        $this->actionEventView($alert, $event);
    }

    public function actionNullEventUpdate($alert, $event, $params) {
        
    }

    public function actionTakeCharge($id) {
        $alert = $this->loadModel($id);

        if ($alert->isManaged())
            Yii::app()->user->setFlash('warning', t('Alert already managed'));
        else if ($alert->isTakenInCharge())
            Yii::app()->user->setFlash('warning', t('Alert already taken in charge'));
        else {
            $operator = Yii::app()->user->model;
            $alert->takeCharge($operator);

            Yii::app()->user->setFlash('success', t('Successfully taken in charge'));
        }

        if (Yii::app()->request->isAjaxRequest)
            $this->renderPartial('_alertRow', array(
                'alert' => new AlertPresenter($alert)
            ));
        else
            $this->redirect(array(
                '/alert/view',
                'id' => $id
            ));
    }

    public function actionDelete($id, $returnUrl = null) {
        access_denied_check('alert_delete');

        if (isEmpty($returnUrl))
            $returnUrl = url('');

        $alert = $this->loadModel($id);
        $alert->delete();

        $this->redirect($returnUrl);
    }

    public function actionUpdate($id) {
        $alert = $this->loadModel($id);
        $alert->attributes = $_POST ['Alert'];
        $alert->just_modified = true;

        if (!$alert->isManaged())
            $alert->manage(Yii::app()->user->model);
        $alert->save();
        $event = $alert->associatedEvent;
        if (isset($event)) {
            $klass = get_class($event);
            $actionName = "action{$klass}update";
            $this->$actionName($alert, $event, $_POST [$klass]);
        }
        Yii::app()->end();
    }

    public function actionManage($id) {
        $alert = $this->loadModel($id);

        if ($alert->isManaged())
            Yii::app()->user->setFlash('warning', t('Alert already managed'));
        else {
            $operator = Yii::app()->user->model;
            $alert->Manage($operator);
        }

        $this->renderPartial('_alertRow', array(
            'alert' => new AlertPresenter($alert)
        ));
    }

    public function actionReleaseCharge($id) {
        $alert = $this->loadModel($id);
        $operator = Yii::app()->user->model;
        $alert->releaseCharge($operator);

        $this->renderPartial('_alertRow', array(
            'alert' => new AlertPresenter($alert)
        ));
    }

    public function actionSummary() {
        $model = Alert::model();
        $model->new()
                ->groupByType();
        $query = $model->getDbCriteria();
        $query = $model->selectForCount($query);

        $dataProvider = new CActiveDataProvider('Alert', array(
            'pagination' => false
        ));

        $dataProvider->criteria = $query;
        $this->renderPartial('_alertSummaryBox', array(
            'data' => $dataProvider
        ));
    }

    /**
     *
     * @param unknown $id          
     * @param boolean $throwOnNull
     *          default=true
     * @throws CHttpException
     * @return Alert
     */
    public function loadModel($id, $throwOnNull = true) {
        $model = Alert::model()->findByPk($id);
        if ($model === null && $throwOnNull)
            throw new CHttpException(404, Yii::t('app', 'The requested page does not exist.'));
        return $model;
    }

    public function varsForWLSmartTips($event, $gate, $timestamp, $nationality, $plate) {


        // turn the plate uppercase and remove non alphanumeric characters, if any
        $plate = strtoupper($plate);
        $plate = preg_replace("/[^A-Za-z0-9]/", '', $plate);

        $permessi = PlateAuthorization::findSmartByPlate(
                        $plate, $nationality, PlateAuthorization::FIND_SMART_BY_PLATE_FILTERUSERLIST_WHITELIST
        );



        $liste = array();
        $nomiListe = array();
        $permessiAttivi = array();
        foreach ($permessi as $p) {

            if (!in_array($p->IDLista, $liste)) {
                $liste[] = $p->IDLista;
                $nomiListe[$p->IDLista] = $p->Lista;
            }
            if ($p->allowed($gate, $timestamp)) {
                $permessiAttivi[] = $p;
            }
        }


        $Lists = PlateList::model()->importRunning()->findAll();



        $importRunning = (count($Lists) > 0);



        $vars ['gate'] = $gate;
        $vars ['timestamp'] = $timestamp;
        $vars ['nationality'] = $nationality;
        $vars ['plate'] = $plate;
        $vars ['permessi'] = $permessi;
        $vars ['liste'] = $liste;
        $vars ['nomiListe'] = $nomiListe;
        $vars ['permessiAttivi'] = $permessiAttivi;

        return $vars;
    }

}
