<?php

namespace Vn\Web;

require_once (__DIR__.'/rest-service.php');
require_once (__DIR__.'/json-request.php');
require_once (__DIR__.'/json-reply.php');

use Vn\Lib;

/**
 * Base class for JSON application.
 **/
class JsonService extends RestService
{
	private $warnings = NULL;

	function run ()
	{
		ini_set ('display_errors', FALSE);
		set_error_handler ([$this, 'errorHandler'], E_ALL);
		set_exception_handler ([$this, 'exceptionHandler']);

		$this->startSession ();

		// Checks the client version

		if (!empty ($_COOKIE['vn_version']))
			$clientVersion = (int) $_COOKIE['vn_version'];

		if (isset ($clientVersion)
		&& $clientVersion < $this->getVersion ())
			throw new OutdatedVersionException ();

		$method = $this->app->loadMethod (
			$_REQUEST['method'], __NAMESPACE__.'\JsonRequest', './rest');
		$json = $method->runRest ();
		$this->replyJson ($json);
	}
	
	function replyJson ($jsonData)
	{
		$reply = new JsonReply ();
		$reply->data = $jsonData;
		$reply->warnings = $this->warnings;

		header ('Content-Type: application/json; charset=UTF-8');
		echo json_encode ($reply);
	}

	function errorHandler ($errno, $message, $file, $line, $context)
	{
		$eUserWarn =
			  E_USER_NOTICE
			| E_USER_WARNING
			| E_USER_DEPRECATED;
		$eCoreWarn =
			  E_NOTICE
			| E_WARNING
			| E_DEPRECATED;

		$eWarn = $eUserWarn | $eCoreWarn;
		$eUser = $eUserWarn | E_USER_ERROR;

		$json = new JsonException ();
		
		if (_DEBUG_MODE || $errno & $eUser)
			$json->message = $message;
		else
			$json->message = 'Something went wrong';
		
		if (_DEBUG_MODE)
		{
			$json->code = $errno;
			$json->file = $file;
			$json->line = $line;
		}

		if ($errno & $eWarn)
		{
			if (!isset ($this->warnings))
				$this->warnings = [];
	
			$this->warnings[] = $json;
		}
		else
		{
			http_response_code (500);
			$this->replyJson ($json);
			exit ();
		}
		
		return !($errno & $eUser);
	}
	
	function exceptionHandler ($e)
	{
		$json = new JsonException ();
		
		if (_DEBUG_MODE || $e instanceof Lib\UserException)
		{
			$json->exception = get_class ($e);
			$json->message = $e->getMessage ();
		}
		else
		{
			$json->exception = 'Exception';
			$json->message = 'Something went wrong';
		}

		if (_DEBUG_MODE)
		{
			$json->code = $e->getCode ();
			$json->file = $e->getFile ();
			$json->line = $e->getLine ();
			$json->trace = $e->getTraceAsString ();
		}

		$this->statusFromException ($e);
		$this->replyJson ($json);
		
		if (!($e instanceof Lib\UserException))
			throw $e;
	}
}

?>