<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Exceptions extends CI_Exceptions
{
	var $result = array();
	var $is_json_result = false;
	 public function __construct()
	{
		parent::__construct();
		$this->CI =& get_instance();
	}
	
	/**
	 * Exception Logger
	 *
	 * Logs PHP generated error messages
	 *
	 * @param	int	$severity	Log level
	 * @param	string	$message	Error message
	 * @param	string	$filepath	File path
	 * @param	int	$line		Line number
	 * @return	void
	 */
	public function log_exception($severity, $message, $filepath, $line)
	{
		$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
		log_message('error', '['.$_SERVER['REQUEST_URI'].'] Severity: '.$severity.' --> '.$message.' '.$filepath.' '.$line);
	}

	// --------------------------------------------------------------------

	/**
	 * 404 Error Handler
	 *
	 * @uses	CI_Exceptions::show_error()
	 *
	 * @param	string	$page		Page URI
	 * @param 	bool	$log_error	Whether to log the error
	 * @return	void
	 */
	public function show_404($page = '', $log_error = TRUE)
	{
		if (is_cli())
		{
			$heading = 'Not Found';
			$message = 'The controller/method pair you requested was not found.';
		}
		else
		{
			$heading = '404 Page Not Found';
			$message = 'The page you requested was not foundas.';
		}

		// By default we log this, but allow a dev to skip it
		if ($log_error)
		{
			log_message('error', $heading.': '.$page);
		}

		echo $this->show_error($heading, $message, 'error_404', 404);
		exit(4); // EXIT_UNKNOWN_FILE
	}

	// --------------------------------------------------------------------

	/**
	 * General Error Page
	 *
	 * Takes an error message as input (either as a string or an array)
	 * and displays it using the specified template.
	 *
	 * @param	string		$heading	Page heading
	 * @param	string|string[]	$message	Error message
	 * @param	string		$template	Template name
	 * @param 	int		$status_code	(default: 500)
	 *
	 * @return	string	Error page output
	 */
	 
	public function show_error_json($err,$error_code='500')
	{
		// $request = $_REQUEST;
		// $this->result['request']['data'] 	= $request;
		$this->result['statusCode']			= 0;
		$this->result['message']			= $err;
		header('Content-Type: application/json');
		header("HTTP/1.1 ".$error_code." Internal Server Error");
		echo json_encode($this->result);
		exit;
	}
	 
	public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
	{
		$templates_path = config_item('error_views_path');
		$cli_type		= '';
		if (empty($templates_path))
		{
			$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
		}

		if (is_cli())
		{
			$message = "\t".(is_array($message) ? implode("\n\t", $message) : $message);
			$template = 'cli'.DIRECTORY_SEPARATOR.$template;
			$cli_type		= 'cli';
		}
		else
		{
			set_status_header($status_code);
			$message = '<p>'.(is_array($message) ? implode('</p><p>', $message) : $message).'</p>';
			$template = 'html'.DIRECTORY_SEPARATOR.$template;
			$cli_type		= 'html';
		}

		if (ob_get_level() > $this->ob_level + 1)
		{
			ob_end_flush();
		}
		ob_start();
		include($templates_path.$template.'.php');
		$buffer = ob_get_contents();
		ob_end_clean();
		if(!$this->is_json_result)
		{
			return $buffer;
		}else{
			$this->result['error']['error_type'] =$cli_type;
			$this->result['error']['exception_type'] =get_class($exception);
			$this->result['error']['template'] =$templates_path;
			$this->result['error']['file_path'] =$exception->getFile();
			$this->result['error']['line_number'] =$exception->getLine();
			$this->result['error']['message'] =$message;
			$this->result['error']['page'] =$page;
			$this->result['error']['heading'] =$heading;
			$this->show_error_json($message,$status_code);
		}
	}

	// --------------------------------------------------------------------

	public function show_exception($exception)
	{
		$templates_path = config_item('error_views_path');
		$cli_type		= '';
		if (empty($templates_path))
		{
			$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
		}

		$message = $exception->getMessage();
		if (empty($message))
		{
			$message = '(null)';
		}

		if (is_cli())
		{
			$templates_path .= 'cli'.DIRECTORY_SEPARATOR;
			$cli_type		= 'cli';
		}
		else
		{
			$templates_path .= 'html'.DIRECTORY_SEPARATOR;
			$cli_type		= 'html';
		}

		if (ob_get_level() > $this->ob_level + 1)
		{
			ob_end_flush();
		}

		ob_start();
		include($templates_path.'error_exception.php');
		$buffer = ob_get_contents();
		ob_end_clean();
		/* --- COMMENTED ---*/
		
		if(!$this->is_json_result)
		{
			echo $buffer;
		}else{
			/* --- CUSTOM ERROR TO JSON ---*/
			$this->result['error']['error_type'] =$cli_type;
			$this->result['error']['exception_type'] =get_class($exception);
			// $this->result['error']['template'] =$templates_path;
			$this->result['error']['file_path'] =$exception->getFile();
			$this->result['error']['line_number'] =$exception->getLine();
			// $this->result['error']['message'] =$message;
			$this->show_error_json($message);
		}
	}

	// --------------------------------------------------------------------

	/**
	 * Native PHP error handler
	 *
	 * @param	int	$severity	Error level
	 * @param	string	$message	Error message
	 * @param	string	$filepath	File path
	 * @param	int	$line		Line number
	 * @return	void
	 */
	public function show_php_error($severity, $message, $filepath, $line)
	{
		$templates_path = config_item('error_views_path');
		$cli_type		= '';
		if (empty($templates_path))
		{
			$templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
		}

		$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;

		// For safety reasons we don't show the full file path in non-CLI requests
		if ( ! is_cli())
		{
			$filepath = str_replace('\\', '/', $filepath);
			if (FALSE !== strpos($filepath, '/'))
			{
				$x = explode('/', $filepath);
				$filepath = $x[count($x)-2].'/'.end($x);
			}

			$cli_type		= 'html';
			$template = 'html'.DIRECTORY_SEPARATOR.'error_php';
		}
		else
		{
			$cli_type		= 'cli';
			$template = 'cli'.DIRECTORY_SEPARATOR.'error_php';
		}

		if (ob_get_level() > $this->ob_level + 1)
		{
			ob_end_flush();
		}
		ob_start();
		include($templates_path.$template.'.php');
		$buffer = ob_get_contents();
		ob_end_clean();
		/* --- COMMENTED ---*/
		// echo $buffer;
		if(!$this->is_json_result)
		{
			echo $buffer;
		}else{
			/* --- CUSTOM ERROR TO JSON ---*/
			$this->result['error']['error_type'] =$cli_type;
			$this->result['error']['severity'] =$severity;
			// $this->result['error']['template'] =$templates_path;
			$this->result['error']['file_path'] =$filepath;
			$this->result['error']['line_number'] =$line;
			// $this->result['error']['message'] =$message;
			$this->show_error_json($message);
		}
	}
}
