<?php

namespace Vn\Web;

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->init ();
		$this->startSession ();
		$this->checkVersion ();

		$json = $this->loadMethod (__NAMESPACE__.'\JsonRequest');
		$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 (_ENABLE_DEBUG || $errno & $eUser)
			$json->message = $message;
		else
			$json->message = s('Something went wrong');
		
		if (_ENABLE_DEBUG)
		{
			$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 (_ENABLE_DEBUG || $e instanceof Lib\UserException)
		{
			$json->exception = get_class ($e);
			$json->message = $e->getMessage ();
		}
		else
		{
			$json->exception = 'Exception';
			$json->message = s('Something went wrong');
		}

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

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

