<?php

class ReportController extends Controller
{
  
  public function actionCreate()
  {
    if (! isset ( $_REQUEST ['workPeriodID'] ))
      throw new CHttpException ( 400, Yii::app ( 't', 'workPeriodID is required.' ) );
    
    $workPeriodID = ( int ) $_REQUEST ['workPeriodID'];
    
    $this->showReport ( $workPeriodID, false );
  }

  public function actionPreview()
  {
    if (! isset ( $_REQUEST ['workPeriodID'] ))
      throw new CHttpException ( 400, Yii::app ( 't', 'workPeriodID is required.' ) );
    
    $workPeriodID = ( int ) $_REQUEST ['workPeriodID'];
    
    $this->showReport ( $workPeriodID, true );
  }
  
  
  public function actionCreateByService()
  {
  	if (! isset ( $_REQUEST ['serviceID'] ))
  		throw new CHttpException ( 400, Yii::app ( 't', 'serviceID is required.' ) );
  		
  		$serviceID= ( int ) $_REQUEST ['serviceID'];
  		
  		$this->showReportByService( $serviceID, false );
  }
  
  public function actionPreviewByService()
  {
  	if (! isset ( $_REQUEST ['serviceID'] ))
  		throw new CHttpException ( 400, Yii::app ( 't', 'serviceID is required.' ) );
  		
  		$serviceID= ( int ) $_REQUEST ['serviceID'];
  		
  		$this->showReportByService( $serviceID, true );
  }

  /**
   *
   * @param integer $workPeriodID          
   * @param boolean $preview          
   */
  protected function showReport($workPeriodID, $preview)
  {
    $period = $this->loadWorkPeriod ( $workPeriodID );
    
    $report = new Report (); // approved and invalid
    $report->initByWorkPeriod($period, false);
    
    if (! $preview)
    {
      $events = EventTagger::tag ( $report->repository->all );
    }
    else
    {
      $events = array_convert ( $report->repository->all, function (Event $e)
      {
        $e->ext_code = $e->validation_result == 'approved' ? 'DEMO' : ExtCode::NULL_EXT_CODE;
        return $e;
      } );
    }
    
//    if ($period->report_generation_date == NULL)
    {
      $converterEventToId = function (Event $e)
      {
        return $e->ID;
      };
      
      $reportApproved = new Report (); // approved only
      $reportApproved->initByWorkPeriod($period, true);
      
      $eventsApproved = $reportApproved->repository->all;
      
	  if (! $preview)
      {
      	$period->report_generation_date = new DateTime ();
        $period->events_count = count ( $eventsApproved );
        $period->events_ids = implode ( ",", array_convert ( $eventsApproved, $converterEventToId ) );
        $period->activateRegistration();
        $period->save ();
      }
    }
    
    //$this->registerAllExportCounters();

    $eventsByGateGroup = GroupEventsByGateGroup::run ( $events );
    
    // this will hold data we will pass to views for rendering
    $reportData = array(
    	'user' => $period->user,
    	'period' => $period,
    	'generationTime' => DateHelper::formatDateTime($period->report_generation_date)
    );
    
    $reportPrinter = ReportPrinterFactory::getReportPrinter();

    foreach ($eventsByGateGroup as $aGroup) {
    	
    	$gateGroup = $aGroup['gateGroup'];
    	$events = $aGroup['events'];
    	$events = array_sort($events, function($a,$b){ $a = new DateTimeEx($a->StartTime); return $a->compare(new DateTimeEx($b->StartTime)); });
    	$totalEvents = count($events);
    	$validEvents = array_filter($events, function($e){return $e->ext_code != ExtCode::NULL_EXT_CODE;});
    	$firstEvent = array_first($validEvents);
    	$lastEvent = array_last($validEvents);
    	$gates = $gateGroup->gates;
    	
    	// fill report data to render
    	$reportData['counterOK'] = 0;
    	$reportData['counterNO'] = 0;
    	foreach($events as $event) {
    		if ($event->ext_code != ExtCode::NULL_EXT_CODE) {
    			$reportData['counterOK']++;
    		}
    		else {
    			$reportData['counterNO']++;
    		}
    	}
    	$reportData['gateGroup'] = $aGroup['gateGroup'];
    	//$reportData['events'] = $aGroup['events'];
    	$reportData['events'] = $events;
    	$reportData['totalEvents'] = count($events);
    	$reportData['validEvents'] = $validEvents;
    	$reportData['firstEvent'] = $firstEvent;
    	$reportData['lastEvent'] = $lastEvent;
    	$reportData['gates'] = $gateGroup->gates;
    	
    	// build a temporary ReportDocument to use,
    	// we will persist it later if necessary
    	$reportDocument = new ReportDocument();
    	$reportDocument->UserID = $period->id_user;
    	$reportDocument->PeriodID = $period->id;
    	$reportDocument->serviceID = 0;
    	$reportDocument->GroupID = $gateGroup->ID;
    	$reportDocument->CreationTime = $period->report_generation_date;
    	$reportDocument->MinExtcode = $firstEvent->ext_code;
    	$reportDocument->MaxExtcode = $lastEvent->ext_code;
    	$reportDocument->approved_events = $validEvents;
    	
    	// get the report title
    	$title = $reportDocument->getTitle();
    	
    	// build the PDF report and store it in an
    	// array we will pass to the view
    	$pdfs[$reportData['gateGroup']->name] = $reportPrinter->printReport($title, $reportData);
    	if (!$preview) {
    		
    		// set the PDF content
    		$reportDocument->Document = end($pdfs);
    		
    		// persist document on DB
    		$res = $reportDocument->save();
    	}
    	
    }
    
    if (!$preview && !$period->closed) {
    	
    	// force user logout
    	Yii::app ()->user->logout();
    	
    	// redirect to login page
    	$this->redirect(array("session/login/"));
    	
    }
    else if (!$preview) {
    	
    	// redirect to report archive view
    	$this->redirect(array("reportArchive/index/"));
    	
    }
    else {
    	
    	// render report preview page
    	$this->render('sessionReportsPreviewViewer', array('pdfs' => $pdfs, 'workPeriod' => $period));
    	
    }
    
  }
  
  
  /**
   *
   * @param integer $workPeriodID
   * @param boolean $preview
   */
  protected function showReportByService($serviceID, $preview)
  {
  	$service = $this->loadService ( $serviceID);

  	$report = new Report (); // approved and invalid
  	$report->initByService( $service, false ); // approved and invalid


  	if (! $preview)
  	{
  		$events = EventTagger::tag ( $report->repository->all );
  	}
  	else
  	{
  		$events = array_convert ( $report->repository->all, function (Event $e)
  		{
  			$e->ext_code = $e->validation_result == 'approved' ? 'DEMO' : ExtCode::NULL_EXT_CODE;
  			return $e;
  		} );
  	}
  	
  	//    if ($period->report_generation_date == NULL)
  	{
  		$converterEventToId = function (Event $e)
  		{
  			return $e->ID;
  		};
  		
  		$reportApproved = new Report (); // approved only
  		$reportApproved->initByService($service, true); // approved only
  		
  		$eventsApproved = $reportApproved->repository->all;
  		
  		if (! $preview)
  		{
  			$service->report_generation_date = new DateTime ();
  			$service->report_user= $service->assignedOperator->id;
  			$service->id_user_validating = 0;
  			$service->activateRegistration();
  			$service->save ();
  		}
  	}

  	//$this->registerAllExportCounters();

  	$eventsByGateGroup = GroupEventsByGateGroup::run ( $events );

  	
  	// this will hold data we will pass to views for rendering
  	$reportData = array(
  			'user' => $service->assignedOperator,
  			'period' => null,
  			'generationTime' => DateHelper::formatDateTime($service->report_generation_date)
  	);
  	
  	

  	
  	$reportPrinter = ReportPrinterFactory::getReportPrinter();
  	
  	
  	foreach ($eventsByGateGroup as $aGroup)
  	{

  		
  		$gateGroup = $aGroup['gateGroup'];
  		$events = $aGroup['events'];
  		$events = array_sort($events, function($a,$b){ $a = new DateTimeEx($a->StartTime); return $a->compare(new DateTimeEx($b->StartTime)); });
  		$totalEvents = count($events);
  		$validEvents = array_filter($events, function($e){return $e->ext_code != ExtCode::NULL_EXT_CODE;});
  		$firstEvent = array_first($validEvents);
  		$lastEvent = array_last($validEvents);
  		$gates = $gateGroup->gates;
  		
  		// fill report data to render
  		$reportData['counterOK'] = 0;
  		$reportData['counterNO'] = 0;
  		foreach($events as $event) {
  			if ($event->ext_code != ExtCode::NULL_EXT_CODE) {
  				$reportData['counterOK']++;
  			}
  			else {
  				$reportData['counterNO']++;
  			}
  		}
  		$reportData['gateGroup'] = $aGroup['gateGroup'];
  		//$reportData['events'] = $aGroup['events'];
  		$reportData['events'] = $events;
  		$reportData['totalEvents'] = count($events);
  		$reportData['validEvents'] = $validEvents;
  		$reportData['firstEvent'] = $firstEvent;
  		$reportData['lastEvent'] = $lastEvent;
  		$reportData['gates'] = $gateGroup->gates;
  		
  		// build a temporary ReportDocument to use,
  		// we will persist it later if necessary
  		$reportDocument = new ReportDocument();
  		$reportDocument->UserID = $service->assignedOperator->id;
  		$reportDocument->PeriodID = 0;
  		$reportDocument->serviceID = $service->ID;
  		$reportDocument->GroupID = $gateGroup->ID;
  		$reportDocument->CreationTime = $service->report_generation_date;
  		$reportDocument->MinExtcode = $firstEvent->ext_code;
  		$reportDocument->MaxExtcode = $lastEvent->ext_code;
  		$reportDocument->total_events = $totalEvents;
  		$reportDocument->approved_events = $validEvents;
  		$reportDocument->invalid_events =count($events) - count($validEvents);
  		$reportDocument->uuid = getGUID();

  		
  		$eventReg =  NULL;
  		if(paramdeep ( 'security', 'send_export_registration' ))
  		    $eventReg = EventServerRegistration::model()->byMe()->find();
  		
  		if(!isEmpty($eventReg))
  		    $reportDocument->id_eventserver = $eventReg->id;
  		else
  		    $reportDocument->id_eventserver = 0;
  		    
  		    
  		// get the report title
  		$title = $reportDocument->getTitle();
  		
  		

  		
  		// build the PDF report and store it in an
  		// array we will pass to the view
  		$pdfs[$reportData['gateGroup']->name] = $reportPrinter->printReport($title, $reportData);
  		

  		
  		if (!$preview)
  		{
  			
  			// set the PDF content
  			$reportDocument->Document = end($pdfs);
  			
  			// persist document on DB
  			if(!$reportDocument->save())
  			{
  			
  				echo ($reportDocument->getErrors());
  			}

  			
  		}

  	}
  	

  	if (!$preview) {
  		
  		// redirect to report archive view
  		$this->redirect(array("reportArchive/index/"));
  		
  	}
  	else {
  		
  		// render report preview page
  		$this->render('sessionReportsPreviewViewerByService', array('pdfs' => $pdfs, 'service' => $service));
  		
  	}

  }
  
  
  
  
  public function actionDoRegisterAllExportCounters()
  {
  	$this->registerAllExportCounters();
  }
  
  public function actionConfirm($workPeriodID)
  {
  	$checkExpDay = paramdeep ( 'security', 'export_expiry_date_check' );
  	
  	if(!isEmpty($checkExpDay) && $checkExpDay)
  	{
	  	$EventServerReg = EventServerRegistration::model()->byMe()->find();
	  	
	  	if(isEmpty($EventServerReg))
	  	{
	  		$this->renderPartial ( '_licenseConnectionFailed');
	  		return;
	  	}
	  	
	  	
	  	if(isEmpty($EventServerReg->export_expiry_date))
	  	{
	  		$this->renderPartial ( '_licenseExpired');
	  		return;
	  		
	  	}
	  	$nowDate = DateTimeEx::now();
	  	
	  	if($nowDate > $EventServerReg->export_expiry_date)
	  	{
	  		$this->renderPartial ( '_licenseExpired');
	  	}
  	}
  	
    // ensure work period really exists
    $workPeriod = $this->loadWorkPeriod ( $workPeriodID );
    
    $this->renderPartial ( '_confirm', array (
        'workPeriodID' => $workPeriod->id,
        'workPeriodClosed' => $workPeriod->closed 
    ) );
  }

  
  public function actionConfirmByService($serviceID)
  {
  	$checkExpDay = paramdeep ( 'security', 'export_expiry_date_check' );
  	
  	if(!isEmpty($checkExpDay) && $checkExpDay)
  	{
  		$EventServerReg = EventServerRegistration::model()->byMe()->find();
  		
  		if(isEmpty($EventServerReg))
  		{
  			$this->renderPartial ( '_licenseConnectionFailed');
  			return;
  		}
  		
  		
  		if(isEmpty($EventServerReg->export_expiry_date))
  		{
  			$this->renderPartial ( '_licenseExpired');
  			return;
  			
  		}
  		$nowDate = DateTimeEx::now();
  		
  		if($nowDate > $EventServerReg->export_expiry_date)
  		{
  			$this->renderPartial ( '_licenseExpired');
  		}
  	}
  	
  	// ensure work period really exists
  	$service = $this->loadService ( $serviceID);
  	
  	$this->renderPartial ( '_confirmByService', array (
  			'serviceID' => $service->ID
  	) );
  }
  
  
  public function actionViewSummary($workPeriodID)
  {
    $period = $this->loadWorkPeriod ( $workPeriodID );
    $report = new Report ( );
    $report->initByWorkPeriod($period);
    $this->renderPartial ( '/workPeriod/_summary', array (
        'workPeriodID' => $workPeriodID,
        'repository' => $report->repository 
    ) );
  }

  /**
   *
   * @param integer $id          
   * @throws CHttpException
   * @return WorkPeriod
   */
  public function loadWorkPeriod($id)
  {
    $period = WorkPeriod::model ()->findByPk ( $id );
    if ($period === null)
      throw new CHttpException ( 404, Yii::t ( 'app', 'The requested page does not exist.' ) );
    return $period;
  }
  /**
   *
   * @param integer $id
   * @throws CHttpException
   * @return Service
   */
  public function loadService($id)
  {
  	$service= Service::model ()->findByPk ( $id );
  	if ($service=== null)
  		throw new CHttpException ( 404, Yii::t ( 'app', 'The requested run does not exist.' ) );
  		return $service;
  }
  
  public function registerAllExportCounters()
  {
  	$sendExp = paramdeep ( 'security', 'send_export_registration' );
  	if(isEmpty($sendExp) || $sendExp == false)
  		return true;
  	
  		$workPeriods = WorkPeriod::model()->to_register()->findAll();
  		foreach($workPeriods as $wp)
  		{
  			$report = new Report (); // approved and invalid
  			
  			$report->initByWorkPeriod($report, false);
  			
  			if($this->registerExportCounters($report->repository->all, $wp->user, $wp->report_generation_date, $wp->id, 0))
  			{
 		        $wp->confirmRegistration();
		        $wp->save ();
  			}
  		}
  		
 		
  		$services = Service::model()->to_register()->findAll();
  		foreach($services as $sw)
  		{
  			$report = new Report (); // approved and invalid
  			$report->initByService($sw, false);
  			
  			if($this->registerExportCounters($report->repository->all, $sw->registerOperator, $sw->report_generation_date, 0, $sw->ID))
  			{
  				$sw->confirmRegistration();
  				$sw->save ();
  			}
  		}
  		
  }
  
  public function registerExportCounters($events, $user, $ext_code_time, $id_work_period, $id_service)
  {
  	set_time_limit(60);
  	
  	if(count($events) <= 0)
  		return  true;

  	$gates = Gate::model()->findAll();

  	foreach($gates as $gate)
  	{
  		$gateConters[$gate->Gate]['description'] = $gate->Descrizione;
  		$gateConters[$gate->Gate]['exported'] = 0;
  		$gateConters[$gate->Gate]['gate_sn'] = $gate->Gate;
  		$gateConters[$gate->Gate]['gate_type'] = $gate->GateType;
  		$gateConters[$gate->Gate]['gate_model'] = $gate->device_model;
  		$gateConters[$gate->Gate]['deleted'] = 0;
  		$gateConters[$gate->Gate]['plate_changed'] = 0;
  		$gateConters[$gate->Gate]['min_ext_code'] = 0;
  		$gateConters[$gate->Gate]['max_ext_code'] = 0;  		
  	}
  	
  	$gateConters[$event->Gate]['deleted'] = 0;
  	$gateConters[$event->Gate]['plate_changed'] = 0;
  	$gateConters[$event->Gate]['min_ext_code'] = 0;
  	$gateConters[$event->Gate]['max_ext_code'] = 0;
  	$gateConters[$event->Gate]['num_of_events'] = 0;

  	foreach($events as $event)
  	{
  		if ($event->ext_code != ExtCode::NULL_EXT_CODE)  
  		{
  			$gateConters[$event->Gate]['exported'] += 1;
  			
  			if($gateConters[$event->Gate]['min_ext_code'] === 0)
  			{
  				$gateConters[$event->Gate]['min_ext_code'] = $event->ext_code;
  				$gateConters[$event->Gate]['max_ext_code'] = $event->ext_code;
  			}
  			else 
  			{
  				$gateConters[$event->Gate]['min_ext_code'] = min($event->ext_code, $gateConters[$event->Gate]['min_ext_code'] );
  				$gateConters[$event->Gate]['max_ext_code'] = max($event->ext_code, $gateConters[$event->Gate]['max_ext_code'] );
  			}
  		}
  		
  		if ($event->ext_code == ExtCode::NULL_EXT_CODE)
  			$gateConters[$event->Gate]['deleted'] += 1;
  		
  		if (!isEmpty($event->ExtPlate) && $event->ExtPlate != $event->Plate)
  			$gateConters[$event->Gate]['plate_changed'] += 1;
  		
  		$gateConters[$event->Gate]['num_of_events'] += 1;
  	}
  	

  	
  	$eventReg = EventServerRegistration::model()->byMe()->find();
  	
  	if(isEmpty($eventReg))
  		return false;
  	
  		
  	$resSave = true;
  	
  	foreach($gateConters as $gateC)
  	{
  		if($gateC['num_of_events'] > 0)
  		{
  		    if($id_work_period > 0)
  			   $expExisting = ExportedEvents::model()->byServer($eventReg->id)->byGate($gateC['gate_sn'])->byWorkPeriod($id_work_period)->count();
  		    else
  		        $expExisting = ExportedEvents::model()->byServer($eventReg->id)->byGate($gateC['gate_sn'])->byService($id_service)->count();
  		        
  			if($expExisting > 0)
            {
                if($id_work_period > 0)
            	   $expEv = ExportedEvents::model()->byServer($eventReg->id)->byGate($gateC['gate_sn'])->byWorkPeriod($id_work_period)->find();
                else
                    $expEv = ExportedEvents::model()->byServer($eventReg->id)->byGate($gateC['gate_sn'])->byService($id_service)->find();
                    
            	$expEv->export_time = $ext_code_time;
            	$expEv->exported_events =$gateC['exported'] ;
            	$expEv->deleted_events = $gateC['deleted'];
            	$expEv->plate_changes = $gateC['plate_changed'];
            	$expEv->min_ext_code = $gateC['min_ext_code'];
            	$expEv->max_ext_code = $gateC['max_ext_code'];
            	$expEv->id_event_server = $eventReg->id;
            	$expEv->user_name = $user->first_name ." " . $user->last_name;
            	$expEv->gate_sn = $gateC['gate_sn'];
            	$expEv->gate_type = $gateC['gate_type'];
            	$expEv->gate_model = $gateC['gate_model'];
            	$expEv->gate_description = $gateC['description'];
            	$expEv->validated_events = $gateC['num_of_events'] ;
            	$expEv->id_work_period = $id_work_period;
            	$expEv->$id_service = $id_service;
            	$expEv->$id_report = $id_report;
            	
            	if(!$expEv->save())
            		$resSave = false;
            }
            else
            {
  			
		  		$expEv = new ExportedEvents;
		
		  		$expEv->export_time = $ext_code_time;
		  		$expEv->exported_events =$gateC['exported'] ;
		  		$expEv->deleted_events = $gateC['deleted'];
		  		$expEv->plate_changes = $gateC['plate_changed'];
		  		$expEv->min_ext_code = $gateC['min_ext_code'];
		  		$expEv->max_ext_code = $gateC['max_ext_code'];
		  		$expEv->id_event_server = $eventReg->id;
		  		$expEv->user_name = $user->first_name ." " . $user->last_name;
		  		$expEv->gate_sn = $gateC['gate_sn'];
		  		$expEv->gate_type = $gateC['gate_type'];
		  		$expEv->gate_model = $gateC['gate_model'];
		  		$expEv->gate_description = $gateC['description'];
		  		$expEv->validated_events = $gateC['num_of_events'] ;
		  		$expEv->id_work_period = $id_work_period;
		  		$expEv->$id_service = $id_service;
		  		$expEv->$id_report = $id_report;
		  		
		  		if(!$expEv->save())
		  			$resSave = false;
            }
  		}
  	}
  	
  	return $resSave;
  	
  }
}
