<?php

/**
 * Class ToolsController
 *
 * Shows and controls the logs.
 */
class LogsController extends AppBackendController {

	/** @inheritdoc */
	public function beforeFilter() {
		parent::beforeFilter();

		// Set the crumbs
		$this->crumbs = [
			[
				'Logs',
				[
					C => 'logs',
					A => 'usage' ] ]
		];
	}

	# ~ Show the CMS usage - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function usage() {
		$this->crumbs[] = __('Usage log');

		# Get the page
		$page = !empty($this->request->named['page'])
			? (int) $this->request->named['page']
			: 1;

		# If there is request data, that means that filter params have changed
		if (!empty($this->request->data)) {

			# Put new filter params in session and set page to first
			$this->Session->write('LogFilter', $this->request->data);
			$page = 1;
		}

		# Initialize array to store translated values for operation types
		$actionTypes = [
			''       => '',
			'update' => __('Update'),
			'insert' => __('Insert'),
			'delete' => __('Delete') ];
		$this->set('types', $actionTypes);

		# Get all administrators and pass it to view
		$administrator = $this->Administrator->find('all', [
			'fields' => [ 'id', 'full_name' ] ]);

		$availableAdministrators = [];

		$availableAdministrators [''] = '';
		# Convert administrator array to format suitable for select element
		foreach ($administrators as $administrator) {
			$availableAdministrators[$administrator['Administrator']['id']] = $administrator['Administrator']['full_name'];
		}
		$this->set('administrators', $availableAdministrators);

		# Get all available models
		$availableModels = [];

		$models = $this->Module->find('all', [
			'fields' => [ 'name' ] ]);

		$availableModels [''] = '';

		# Convert models array to format suitable for select element
		foreach ($models as $model) {
			$availableModels[$model['Module']['name']] = __(Inflector::humanize(Inflector::tableize($model['Module']['name'])));
		}

		# Prepare pagination
		$paging = [];

		# If there is stored filter, get logs from search function
		$storedFilter = $this->Session->read('LogFilter');
		if (!empty($storedFilter)) {
			$logs = $this->Log->searchLog($this->Session->read('LogFilter'), $page);

			# To show filter form on all pages.
			$this->request->data = $storedFilter;

		} else {
			$logs = $this->Log->find('all', [
					'order'  => 'Log.created DESC',
					'limit'  => 15,
					'offset' => ($page - 1) * 10 ]
			);
		}

		# If there is paging in logs, get other pagination elements from it
		if (!empty($logs['paging'])) {
			$paging['pageCount'] = $logs['paging']['pageCount'];
			$paging['count'] = $logs['paging']['items'];

			# Unset it, so that it cannot be displayed as log item
			unset($logs['paging']);
		} else {

			# Calculate pagination elements
			$countLogs = $this->Log->find('count');
			$paging['pageCount'] = ceil($countLogs / 10);
			$paging['count'] = $countLogs;
		}

		# Store current page
		$paging['page'] = $page;

		# Pass all variables to view
		$this->set('paging', $paging);
		$this->set('models', $availableModels);
		$this->set('logs', $logs);
		$this->set('paginated', true);
		$this->set('modelClass', "Log");
	}

	# ~ System logs	 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function system($delete = false) {

		# Delete the logs
		if ($delete === 'clear') {
			@unlink(LOGS . 'debug.log');
			@unlink(LOGS . 'error.log');
			$this->redirect($this->referer());

		} else {

			# Get the logs
			$log = [];
			$files = [ 'debug', 'error' ];
			$regexp = '~^(?=\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)~ m';
			foreach ($files as $file) {
				$log = array_merge($log, array_filter(preg_split($regexp, @trim(file_get_contents(LOGS . $file . '.log')))));
			}

			# Parse the logs
			foreach ($log as $i => $entry) {
				$match = preg_match('~^(?P<time>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d) (?P<level>[^:]+): (?P<message>.*?)(?:\n(?P<more>(.*\n?)*))?$~ Usim', trim($entry), $entry);
				if ($match) {
					$log[$i] = [
						'time'    => $entry['time'],
						'level'   => strtolower($entry['level']),
						'message' => $entry['message'],
						'more'    => isset($entry['more']) ? $entry['more'] : null
					];
				} else {
					$log[$i] = [
						'time'    => null,
						'level'   => 'unknown',
						'message' => $log[$i],
						'more'    => null
					];
				}
			}

			# Sort by time
			$this->set('log', array_reverse($log));
		}

		# Add shortcut
		$clearURL = Router::url([ 'clear' ]);
		$this->addShortcut('ctrl del', "location.href = '{$clearURL}'");

		# Add crumbs
		$this->crumbs[] = __('System log');
	}

	# ~ API logs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function api() {
		// TODO
	}

	# ~ Clear filter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function clearfilter() {

		# Delete filter data from session and redirect.
		$this->Session->delete('LogFilter');
		$this->redirect([ C => 'logging', A => 'showlog' ]);
	}

}
