<?php
namespace Modules\Utils\AppReports;

/**
 * Controller for AppReports actions
 * @author FlorinRusu
 *
 */
class Controller extends \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing
{

	/**
	 * Password for page authentication
	 * @var string
	 */
	private $token = "DCS+TOKEN";

	/**
	 * The list of columns which support ordering.
	 * @var array
	 */
	protected $listOrderingColumns = [];

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::initialize()
	 */
	protected function initialize()
	{
		parent::initialize();
		$this->actionsCfg['index'] 			= [	'checkSection' => false, 'checkOption' => false];
		$this->actionsCfg['list'] 			= [	'authType' => 'easy', 'checkSection' => false, 'checkOption' => false];
		$this->actionsCfg['listRecords'] 	= [	'authType' => 'easy', 'checkSection'=>false, 'checkOption'=>false];

		$this->actionsCfg['insert'] 		= [	'checkSection' => false, 	'checkOption' => false];
		$this->actionsCfg['update'] 		= [	'checkSection' => false, 	'checkOption' => false];
		$this->actionsCfg['delete'] 		= [	'checkSection' => false, 	'checkOption' => false];
		$this->actionsCfg['generate'] 		= [	'checkSection' => false, 	'checkOption' => false];
		$this->actionsCfg['exportConfig'] 	= [	'checkSection' => false, 	'checkOption' => false];
		$this->actionsCfg['setToken']		= [	'checkSection' => false, 	'checkOption' => false];

		// hide userTrail in db
		\App\UserTrail::getInstance()->storeTrail(false);
	}


	/**
	 *
	 * {@inheritDoc}
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionDefineParams()
	 */
	protected function optionDefineParams(\App\Mvc\View\Utils\RowOptions\Option\Option $option, $selection)
	{
		switch ($option->getId()) {

			case 'insert':	case 'update': 	case 'delete': case 'generate': case 'exportConfig': case 'setToken':
				break;

			default:
				return false;
		}

		return true;
	}

	/**
	 * Action for the password authentication popup
	 * @param array $R
	 * @return \Engine\Mvc\Response\Html
	 */
	protected function actionSetToken($R)
	{
		if (\Engine\Storage\General::getInstance('session')->get('appReportToken') == $this->token) {
			$response = new \Engine\Mvc\Response\HtmlRedirect(\Engine\Mvc\Dispatcher::getInstance()->getAppUrl("Modules/Utils/AppReports", ""));
			return $response;
		}

		$msgs = new \App\MessagesCollector();

		$view = new View_SetToken($this);

		if ($R[$this->formSubmitButtonName]) {
			if ($R['token'] != $this->token) {
				$msgs->addWarning('Token incorrect.');
			}
			else {
				\Engine\Storage\General::getInstance('session')->set('appReportToken', $R['token']);

				// redirect to index section
				$response = new \Engine\Mvc\Response\HtmlRedirect(\Engine\Mvc\Dispatcher::getInstance()->getAppUrl("Modules/Utils/AppReports", ""));
				return $response;
			}
		}


		$view->getMessagesCollector()->appendMessages($msgs);
		return new \Engine\Mvc\Response\Html($view->render());

	}

	/**
	 * Action to export a part/all configs as XML
	 * @return \Engine\Mvc\Response\Html
	 */
	protected function actionExportConfig($R)
	{
		$shouldRedirect = $this->checkTokenAndRedirect();
		if ($shouldRedirect) {
			return $shouldRedirect;
		}

		$msgs = new \App\MessagesCollector();

		$formData = $R;

		$exportCfgObj = new ExportCfgManager($R['exportOptions']);


		$view = new View_ExportConfig($this);

		// send data to the view
		$view->addInput('formData', $formData);
		$view->addInput('formSubmitButtonName', $this->formSubmitButtonName);

		// execute the model (and collect the output)
		if ($R[$this->formSubmitButtonName]) {

			try {

				$zipPath = $exportCfgObj->createArchive();

				$response = new \Engine\Mvc\Response\FileDownload(\Engine\File::getContents($zipPath));
				$response->setFilename('config.zip');

				// delete the temporary zip file now also
				\Engine\Dir::delete($zipPath);

				return $response;

			}
			catch (\App\MessagesException $e) {
				$msgs->appendMessages($e->getMessagesCollector());
			}

		}

		$view->getMessagesCollector()->appendMessages($msgs);
		return new \Engine\Mvc\Response\Html($view->render());


	}

	/**
	 * Action to download a generate file based on the sql value in the current row
	 * @param array $R
	 * @return \Engine\Mvc\Response\FileDownload|\Engine\Mvc\Response\Html
	 */
	protected function actionGenerate($R)
	{
		$shouldRedirect = $this->checkTokenAndRedirect();
		if ($shouldRedirect) {
			return $shouldRedirect;
		}

		$CFG = \Engine\Loader_Cfg::getInstance()->getGlobal();

		$appReport = \Modules\Utils\AppReports\SqlManager::getInstance()->get($R['id']);
		$tempFileName = APP_REAL_PATH.$CFG['paths']['temporary'].'appReport.csv';

		$msgs = new \App\MessagesCollector();

		$executeSqlModel = new \Modules\Utils\CollectInfo\Model\ExecuteSql($appReport['sql'], $appReport['monthTable']);

		try {

			$reportData = $executeSqlModel->getResponse();

			if ($reportData) {
				$reportData = array_merge([array_keys($reportData[0])], $reportData);
				// CREATE REPORT ON DISK --------------------------------------------------------------
				$f=fopen($tempFileName, 'w');
				foreach ($reportData as $record) {
					fputcsv($f, $record, ",", "\"", "");
				}
				fclose($f);
				unset($reportData);

				$response = new \Engine\Mvc\Response\FileDownload(\Engine\File::getContents($tempFileName));
				$response->setFilename($appReport['name'].'.csv');
				return $response;
			}
			else {
				$msgs->addSuccess('No records according to this SQL.');
			}

		}
		catch (\App\MessagesException $ex) {
			$msgs->appendMessages($ex->getMessagesCollector());
		}

		$view = new View_Generate($this);
		$view->getMessagesCollector()->appendMessages($msgs);

		return new \Engine\Mvc\Response\Html($view->render());
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::insert_getDefaultFormData()
	 */
	protected function insert_getDefaultFormData($R)
	{
		return [];
	}


	/**
	 * Does the actual "insert" operation upon form submit.
	 */
	protected function insert_doInsert($formData, \App\MessagesCollector $msgs)
	{

		$appReportAdmin = \Modules\Utils\AppReports\SqlManager::getAdmin();

		$reportData = [
			'name'			=>	$formData['name'],
			'sql'			=>  htmlUnclean($formData['sql']),
			'monthTable'	=>	$formData['monthTable'],
		];

		try {
			$appReportAdmin->itemInsert($formData['name'], $reportData);
			$appReportAdmin->save();
			$msgs->addSuccess("The app report has been added successfully");
			$this->insertIdRecord = $reportData['name'];
			return true;
		}
		catch (\App\Config\MessageException $e) {
			$msgs->addWarning($e->getMessage());
			return false;
		}
	}


	/**
	 * Returns an array of default values for "update" form.
	 * @return Array
	 */
	protected function update_getDefaultFormData($id)
	{
		return \Modules\Utils\AppReports\SqlManager::getInstance()->get($id);
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedEntityListing::update_createEntityObject()
	 */
	protected function update_doUpdate($formData, \App\MessagesCollector $msgs)
	{

		$appReportAdmin = \Modules\Utils\AppReports\SqlManager::getAdmin();
		$item = $appReportAdmin->get($formData['id']);

		$appReportDetails = [
			'name'				=>	$item['name'],
			'sql'				=>	htmlUnclean($formData['sql']),
			'monthTable'		=>	$formData['monthTable'],
		];


		try {
			$appReportAdmin->itemUpdate($formData['id'], $appReportDetails);
			$appReportAdmin->save();
			// show success message
			$msgs->addSuccess("The app report has been updated successfully");
			return true;
		}
		catch (\App\Config\MessageException $e) {
			// show error message
			$msgs->addWarning($e->getMessage());
			return false;
		}

	}



	/**
	 * {@inheritDoc}
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::delete_doDelete()
	 */
	protected function delete_doDelete(array $recordsIds, \App\MessagesCollector $msgs, array $R)
	{

		$appReportsAdmin = \Modules\Utils\AppReports\SqlManager::getAdmin();

		foreach ($recordsIds as $record) {

			try {

				$appReportsAdmin->itemDelete($record);
				$appReportsAdmin->save();
				// remove this record from the internal list
				$this->getListingSelection()->delete([$record]);
				$msgs->addSuccess("The configuration(s) has been deleted successfully.");

			}
			catch (\App\Config\MessageException $e) {

				$msgs->addError($e->getMessage());

			}
		}
	}


	/**
	 *
	 * {@inheritDoc}
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::actionIndex()
	 */
	protected function actionIndex($R)
	{
		$shouldRedirect = $this->checkTokenAndRedirect();
		if ($shouldRedirect) {
			return $shouldRedirect;
		}

		return parent::actionIndex($R);
	}


	/**
	 *
	 * {@inheritDoc}
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::actionInsert()
	 */
	protected function actionInsert($R)
	{
		$shouldRedirect = $this->checkTokenAndRedirect();
		if ($shouldRedirect) {
			return $shouldRedirect;
		}

		return parent::actionInsert($R);
	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::actionUpdate()
	 */
	protected function actionUpdate($R)
	{
		$shouldRedirect = $this->checkTokenAndRedirect();
		if ($shouldRedirect) {
			return $shouldRedirect;
		}

		return parent::actionUpdate($R);
	}

	/**
	 *
	 * {@inheritDoc}
	 * @see \App\Mvc\Controller\Window\PaginatedListing\PaginatedListing::bulkActionDelete()
	 */
	protected function bulkActionDelete($recordsIds, $msgs, $R)
	{
		$shouldRedirect = $this->checkTokenAndRedirect();
		if ($shouldRedirect) {
			return $shouldRedirect;
		}

		return parent::bulkActionDelete($recordsIds, $msgs, $R);
	}


	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionGetEntityName()
	 */
	protected function optionGetEntityName($id)
	{
		return $id;
	}

	/**
	 * Method that compares the private token with the one in the session and redirects to the setToken in case they are not equal
	 * @return \Engine\Mvc\Response\HtmlRedirect|NULL
	 */
	private function checkTokenAndRedirect()
	{
		if (\Engine\Storage\General::getInstance('session')->get('appReportToken') != $this->token) {
			$response = new \Engine\Mvc\Response\HtmlRedirect(\Engine\Mvc\Dispatcher::getInstance()->getAppUrl("Modules/Utils/AppReports", "setToken"));
			return $response;
		}

		return null;
	}


}