<?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)
  {
    $operator = Yii::app ()->user->model;
    $this->render ( 'viewVehicleTrace', array (
        'alert' => $alert,
        'event' => $event,
        'editEnable' => $alert->canEdit ( $operator->id ) 
    ) );
  }

  public function actionNullEventView($alert, $event)
  {
    $operator = Yii::app ()->user->model;
    $this->render ( 'viewGenericAlert', array (
        'alert' => $alert,
        'editEnable' => $alert->canEdit ( $operator->id ) 
    ) );
  }

  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)
  {
    $operator = Yii::app ()->user->model;
    $this->render ( 'viewEvent', array (
        'alert' => $alert,
        'event' => $event,
        'editEnable' => $alert->canEdit ( $operator->id ) 
    ) );
  }

  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;
  }
}
