<?php

/**
 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @package fusionLib
 * @copyright Copyright (c) 2007 - 2013 fusionLib. All rights reserved.
 * @link http://fusionlib.com
 */

/**
 * flExceptionReporter Class
 *
 * Class to report errors and exceptions to the user in a controlled fashion.
 *
 * @uses flExceptionErrorController If an errorController is derived from it to
 * handle the errors in a custom way.
 *
 * @package fusionLib
 */
class flExceptionReporter {

	/**
	 * Flags if full debug should be shown.
	 *
	 * @var bool
	 */
	static private $showFullDebug = false;

	/**
	 * The request object.
	 *
	 * @var flRequest
	 */
	static private $request = null;

	/**
	 * The router object.
	 *
	 * @var flRouter
	 */
	static private $router = null;

	/**
	 * Switches on the display of stack trace information.
	 */
	static function showFullDebug() {
		self::$showFullDebug = true;
	}

	/**
	 * Gets full debug status.
	 *
	 * @return bool true if using full debug.
	 */
	static function withFullDebug() {
		return self::$showFullDebug;
	}

	/**
	 * Set the router and request to use for the error controller.
	 *
	 * @param flRouter $router The router object.
	 * @param flRequest $request The request object.
	 */
	static function setRouterRequest($router, $request) {
		self::$router = $router;
		self::$request = $request;
	}

	/**
	 * Show exception.
	 *
	 * @param flException $e The exception to show.
	 */
	static function showException($e) {
		// Discard any active output buffers
		while(@ob_end_clean());

		// Remove base folder from the filename and message, it's best not to let people see it
		$file = preg_replace('/^' . ($exp = preg_quote(FLROOTPATH, '/')) . '/', '', $e->getFile());
		$message = preg_replace('/' . $exp . '/', '', $e->getMessage());

		// If invoked via a web browser
		if(isset($_SERVER['SERVER_NAME'])) {
			// If headers sent or no application class then try to output something usable
			if(headers_sent() || !class_exists('flApp', false)) {
				echo str_replace(array(
					'[[+code]]',
					'[[+name]]',
					'[[+message]]',
					'[[+fileline]]',
					'[[+backtrace]]'
				), array(
					$e->getCode(),
					$e->getName(),
					nl2br($message),
					self::$showFullDebug ? "<p><strong>File:</strong> $file<br /><strong>Line:</strong> " . $e->getLine() . '</p>' : '',
					flExceptionErrorController::buildBacktrace($e, true)
				), file_get_contents(FLLIBPATH . 'Exception/errorOverlay.html'));
			}
			// Else output error page
			else {
				try {
					class_exists('errorController');
					$ctrlr = new errorController(self::$router, self::$request, $e);
					$ctrlr->dispatch('error');
				}
				catch(flException $dummy) {
					$ctrlr = new flExceptionErrorController(self::$router, self::$request, $e);
					$ctrlr->dispatch('error');
				}
			}
		}
		// Else format and send error to console
		else {
			echo "\n-------------------- Error --------------------\n\n";
			echo $e->getCode() . ' ' . $e->getName() . ": $message";
			if(self::$showFullDebug) {
				echo "\nin $file on line " . $e->getLine();
				echo "\n\n" . flExceptionErrorController::buildBacktrace($e, false);
			}
			echo "\n\n-----------------------------------------------\n\n";
		}

		die;
	}
}
