<?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 = null) {
		$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;
	}
}