<?php

class Auth
{
	static protected $dbinst;
	static protected $dbpath;

	static public function getTokenOwner($token)
	{
		$stmt = self::getStorage()->prepare("SELECT userId FROM tokens WHERE token=:token AND expire>:expire");
		$stmt->bindValue(':token', $token, PDO::PARAM_STR);
		$stmt->bindValue(':expire', time(), PDO::PARAM_INT);
		$result = $stmt->execute();
		if ($result) {
			$row = $stmt->fetch(PDO::FETCH_NUM);
			return $row[0];
		} else {
			return false;
		}
	}

	static public function addToken($userId, $token, $expire)
	{
		if (empty($token))
			throw new Exception('Empty token');
		$userId = (int)$userId;
		if ($userId <= 0)
			throw new Exception('Empty userId');
		if (is_object($expire)) {
			if  ('DateTime' !== get_class($expire))
				throw new Exception('Wrong expire');
			$expire = $expire->getTimestamp();
		} else {
			$expire = (int)$expire;
			if ($expire<=0)
				throw new Exception('Wrong expire');
		}
		self::getStorage()->beginTransaction();
		//Удаляем старые токены этого пользователя (он мог заходить раньше и выходить/чистить куки
		$stmt = self::getStorage()->prepare("DELETE FROM tokens WHERE userId = $userId");
		$stmt->execute();
		$stmt = self::getStorage()->prepare("INSERT INTO tokens (token, userId, expire) VALUES (:token, :id, :expire)");
		$stmt->bindValue(':token', $token, PDO::PARAM_STR);
		$stmt->bindValue(':id', $userId, PDO::PARAM_INT);
		$stmt->bindValue(':expire', $expire, PDO::PARAM_INT);
		$stmt->execute();
		if (!self::getStorage()->commit()) {
			throw new Exception("SQLite error: userId => $userId, token => $token, expire => $expire");
		}
	}

	static public function deletetoken($userId)
	{
		self::getStorage()->exec("delete from tokens where userId = '$userId'");
	}

	static public function updateToken($token, $expire)
	{
		if (empty($token))
			throw new Exception('Empty token');
		if (is_object($expire)) {
			if  ('DateTime' !== get_class($expire))
				throw new Exception('Wrong expire');
			$expire = $expire->getTimestamp();
		} else {
			$expire = (int)$expire;
			if ($expire<=0)
				throw new Exception('Wrong expire');
		}

		$stmt = self::getStorage()->prepare("UPDATE tokens SET expire=:expire WHERE token=:token");
		$stmt->bindValue(':token', $token, PDO::PARAM_STR);
		$stmt->bindValue(':expire', $expire, PDO::PARAM_INT);
		$stmt->execute();
//		if (!self::getStorage()->commit()) {
//			utls::logStr("auth", "not commited");
//			throw new Exception("SQLite error");
//		}
	}

	/**
	 * Текущая БД (если сайт работает с несколькими)
	 * @return string
	 */
	static public function getCurrentSchema($default = "") {
		$schema = "";
		if (!empty($_SESSION["CURRENT_SCHEMA"])) {
			$schema = $_SESSION["CURRENT_SCHEMA"];
		} else if (!empty($_COOKIE["schema"])) {
			$schema = $_COOKIE["schema"];
		} else if (!empty($default)) {
			$schema = $default;
			self::setCurrentSchema($schema);
		}
		return $schema;
	}
	
	/**
	 * Установка текущей БД (если сайт работает с несколькими)
	 * @param string $schema
	 */
	static public function setCurrentSchema($schema) {
		$_SESSION["CURRENT_SCHEMA"] = $schema;
		$expired = time()+60*60*24*30;
		setcookie("schema", $schema, $expired, '/');
	}

	static public function testLoginAndPassword($login, $password)
	{
		$userId = ora_func("APPL_SYS_USER.CHECK_USER('{$login}', '{$password}')", false);
		$userId = (int)$userId;
		if ($userId <= 0) {
			if ($userId == 0) {
				throw new Exception("No such user", 0);
			} else if ($userId == -1){
				throw new Exception("The account is locked", -1);
			}
		} else {
			return $userId;
		}
	}

	static public function actAs($userId)
	{
		//echo "APPL_SYS_USER.REGISTER_USER('{$userId}')";//td
		//exit;
		ora_proc("APPL_SYS_USER.REGISTER_USER('{$userId}')", false);
		//echo $userId;
		ora_proc("APPL_SYS_USER.USER_IN_SYSTEM('{$userId}')", false);
	}

	static protected function getStorage()
	{
		if (!self::$dbinst)
			self::instDB();
		return self::$dbinst;
	}

	static protected function instDB()
	{

		self::$dbpath = DATA_DIR . '/auth.db3';
		$dsn = 'sqlite:' . self::$dbpath;
		self::$dbinst = new PDO($dsn);
	}


}

?>