<?php

namespace Vn\Web;

require_once ('vn/lib/app.php');
require_once ('vn/lib/util.php');

use Vn\Lib;
use Vn\Lib\Locale;
use Vn\Db\Conn;

/**
 * Thrown when user credentials could not be fetched.
 **/
class SessionExpiredException extends Lib\UserException {}

/**
 * Thrown when user credentials are invalid.
 **/
class BadLoginException extends Lib\UserException {}

/**
 * Thrown when client version is outdated.
 **/
class OutdatedVersionException extends Lib\UserException {}

/**
 * Main class for web applications.
 **/
abstract class App extends Lib\App
{
	protected $conn = NULL;

	/**
	 * Starts the user session.
	 **/
	function startSession ()
	{
		if ($this->isHttps ())
			ini_set ('session.cookie_secure', TRUE);
		
		ini_set ('session.hash_function', 'sha512');
		session_start ();
	
		// Setting the locale

		if (isset ($_SERVER['HTTP_ACCEPT_LANGUAGE']))
		if (!isset ($_SESSION['http_language'])
		|| $_SESSION['http_language'] != $_SERVER['HTTP_ACCEPT_LANGUAGE'])
		{
			$_SESSION['http_language'] = $_SERVER['HTTP_ACCEPT_LANGUAGE'];			
			$regexp = '/([a-z]{1,4})(?:-[a-z]{1,4})?\s*(?:;\s*q\s*=\s*(?:1|0\.[0-9]+))?,?/i';

			preg_match_all ($regexp, $_SERVER['HTTP_ACCEPT_LANGUAGE'], $languages);

			foreach ($languages[1] as $lang)
			if (stream_resolve_include_path ("locale/$lang"))
			{
				$_SESSION['lang'] = $lang;
				break;
			}
		}

		if (!isset ($_SESSION['lang']))
			$_SESSION['lang'] = NULL;
		
		Locale::set ($_SESSION['lang']);

		// Registering the visit

		if (!isset ($_COOKIE['PHPSESSID'])
		|| isset ($_SESSION['access'])
		|| isset ($_SESSION['skipVisit']))
			return;

		$agent = $_SERVER['HTTP_USER_AGENT'];
		$browser = get_browser ($agent, TRUE);
		
		if (isset ($browser['crawler']) && $browser['crawler'])
		{
			$_SESSION['skipVisit'] = TRUE;
			return;
		}

		if (isset ($_SERVER['REMOTE_ADDR']))
			$ip = ip2long ($_SERVER['REMOTE_ADDR']);

		$sysConn = $this->getSysConn ();
		$row = $sysConn->getRow (
			'CALL visit_register (#, #, #, #, #, #, #, #, #)',
			[
				 nullIf ($_COOKIE, 'vn_visit')
				,nullIf ($browser, 'platform')
				,nullIf ($browser, 'browser') 
				,nullIf ($browser, 'version')
				,nullIf ($browser, 'javascript')
				,nullIf ($browser, 'cookies')
				,isset ($agent) ? $agent : NULL
				,isset ($ip) && $ip ? $ip : NULL
				,nullIf ($_SERVER, 'HTTP_REFERER')
			]
		);

		if (isset ($row['access']))
		{
			setcookie ('vn_visit', $row['visit'], time () + 31536000); // 1 Year
			$_SESSION['access'] = $row['access'];
		}
		else
			$_SESSION['skipVisit'] = TRUE;
	}

	/**
	 * Checks if the HTTP connection is secure.
	 *
	 * @return boolean Return %TRUE if its secure, %FALSE otherwise
	 **/
	function isHttps ()
	{
		return isset ($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on';
	}
	
	/**
	 * Obtains the application version number. It is based on de last
	 * modification date of the main script.
	 **/
	function getVersion ()
	{
		return (int) strftime ('%G%m%d%H%M%S',
			filectime (__FILE__ /* $_SERVER['SCRIPT_FILENAME'] */));
	}

	/**
	 * Gets the configuration file name.
	 **/
	function getConfigFile ()
	{
		if (!empty ($_SERVER['SERVER_NAME'])
		&& preg_match ('/^[\w\-\.]+$/', $_SERVER['SERVER_NAME']))
		{
			$hostSplit = explode ('.', $_SERVER['SERVER_NAME']);
			$configDir = _CONFIG_DIR .'/'. $this->name;
			$hostFile = $configDir .'/config.'. $hostSplit[0] .'.php';
		}

		if (isset ($hostFile) && file_exists ($hostFile))
			return $hostFile;
		else
			return parent::getConfigFile ();
	}
}

?>