<?php
/***
	Esta classe é responsável por controlar as sessões entre
	o sistema e os usuários.
***/
class Sessao{
	private $sistema;
	
	function __construct(&$sistema){
		$this->sistema = $sistema;
		$this->inicializar_sessao_php();
	}
	
	/* Método que inicializa a sessão php dependendo do tipo de sistema */
	function inicializar_sessao_php(){
        session_set_cookie_params(604800);

		switch($this->sistema->tipo()){
			case Sistema::WIN7:{
				session_name("win7cliente");
				break;
			}
			case Sistema::WIN7_ADM:{
				session_name("win7adm");
				break;
			}
			case Sistema::INDICACOES:{
				session_name($this->sistema->indicacoes->sessao);
				break;
			}
			case Sistema::GOOGLE_DRIVE:{
				session_name($this->sistema->drive->sessao);
				break;
			}
		}

		session_start();
	}
	
	/* Método que indica se o usuário está logado */
	function logado(){
		return isset($_SESSION['usuario']);
	}
	
	/* 
		Método que faz a tentativa de login para o usuário e senha fornecidos.
		Após finalizar o processo, ele retorna um número que diz se a operação
		foi um sucesso, podendo ser:

		-1: sucesso
		0: usuário ou senha inválidos
		1: erro no banco dados/código
	*/

	function logar($usuario, $senha){
		if(empty($usuario) || empty($senha)){
			return 0;
		}
		try{
			switch($this->sistema->tipo()){
				case Sistema::WIN7:{
					$params = array(':TXT_LOGIN' => $usuario);
					$dados = $this->sistema->bd->executar("SELECT * FROM TBL_CLIENTE WHERE TXT_LOGIN = :TXT_LOGIN", $params, Banco_Dados::FETCH);

					if($this->sistema->bd->quantidade() == 0){ // O nome de usuário não foi encontrado, então logamos um sub-usuário
						return $this->logar_subusuario($usuario, $senha);
					}

					// Inicializamos essa flag que indica se a criptografia da senha é antiga (md5) ou a nova (blowfish)
					$antiga = true;
					if(empty($dados['TXT_SENHA_NOVA'])){ // Se esse campo do banco está vazio, quer dizer que a senha é antiga(md5)
						if($dados['TXT_SENHA'] === md5($senha)){ // Verificamos se a senha está correta
							try{
								// Caso a senha esteja correta, convertemos a criptografia da senha para blowfish
								$dados['TXT_SENHA_NOVA'] = Utilitarios::hash_str($senha);
								$params = array(
									':TXT_LOGIN' => $usuario,
									':TXT_SENHA_NOVA' => $dados['TXT_SENHA_NOVA']
								);
								$this->sistema->bd->executar("UPDATE TBL_CLIENTE SET TXT_SENHA = '', TXT_SENHA_NOVA = :TXT_SENHA_NOVA WHERE TXT_LOGIN = :TXT_LOGIN", $params, Banco_Dados::FETCH);
								$antiga = false;
							}
							catch(Exception $e){ 
								// Se houve qualquer erro na conversão de criptografia, utilizaremos o md5 mesmo
								$antiga = true;
							}
						}
						else{ // A senha não está correta...
							return 0;
						}
					}
					else // O campo do banco que contém a senha em blowfish não está vazio, então devemos usar blowfish e não md5
						$antiga = false;

					// Verificamos se a senha está correta
					$verificada = $antiga ? 
						($dados['TXT_SENHA'] === md5($senha)) :
						(crypt($senha, $dados['TXT_SENHA_NOVA']) === $dados['TXT_SENHA_NOVA']);

					if($verificada){
						$timestamp = time();
						date_default_timezone_set('America/Sao_Paulo');
						$data_alteracao = date('Y-m-d H:i:s', $timestamp);
						$this->sistema->bd->executar("UPDATE TBL_CLIENTE SET NU_ACESSOS_SISTEMA_DATA = :ultimo WHERE TXT_LOGIN = :login", array(
							':login' => $usuario,
							':ultimo' => $data_alteracao
						));

						$this->sistema->logs->adicionar_log_login($dados, 2);

						$usuario = new Usuario_Win7($dados["ID_CLIENTE"]);
						$usuario->carregar($this->sistema->bd);
						$_SESSION["usuario"] = $usuario;
						return -1;
					}
					else
						return 0;
					break;
				}
				case Sistema::WIN7_ADM:{
					$params = array(':TXT_LOGIN' => $usuario);
					$dados = $this->sistema->bd->executar("SELECT * FROM TBL_ADM WHERE TXT_LOGIN = :TXT_LOGIN", $params, Banco_Dados::FETCH);

					if($this->sistema->bd->quantidade() == 0){ // O nome de usuário não foi encontrado
						return 0;
					}

					// Inicializamos essa flag que indica se a criptografia da senha é antiga (md5) ou a nova (blowfish)
					$antiga = true;
					if(empty($dados['TXT_SENHA_NOVA'])){ // Se esse campo do banco está vazio, quer dizer que a senha é antiga(md5)
						if($dados['TXT_SENHA'] === md5($senha)){ // Verificamos se a senha está correta
							try{
								// Caso a senha esteja correta, convertemos a criptografia da senha para blowfish
								$dados['TXT_SENHA_NOVA'] = Utilitarios::hash_str($senha);
								$params = array(
									':TXT_LOGIN' => $usuario,
									':TXT_SENHA_NOVA' => $dados['TXT_SENHA_NOVA']
								);
								$this->sistema->bd->executar("UPDATE TBL_ADM SET TXT_SENHA = '', TXT_SENHA_NOVA = :TXT_SENHA_NOVA WHERE TXT_LOGIN = :TXT_LOGIN", $params, Banco_Dados::FETCH);
								$antiga = false;
							}
							catch(Exception $e){ 
								// Se houve qualquer erro na conversão de criptografia, utilizaremos o md5 mesmo
								$antiga = true;
							}
						}
						else{ // A senha não está correta...
							return 0;
						}
					}
					else // O campo do banco que contém a senha em blowfish não está vazio, então devemos usar blowfish e não md5
						$antiga = false;

					// Verificamos se a senha está correta
					$verificada = $antiga ? 
						($dados['TXT_SENHA'] === md5($senha)) :
						(crypt($senha, $dados['TXT_SENHA_NOVA']) === $dados['TXT_SENHA_NOVA']);

					if($verificada){
						$timestamp = time();
						date_default_timezone_set('America/Sao_Paulo');
						$data_alteracao = date('Y-m-d H:i:s', $timestamp);
						$this->sistema->bd->executar("UPDATE TBL_ADM SET DT_ULTIMO_LOGIN = :ultimo WHERE TXT_LOGIN = :login", array(
							':login' => $usuario,
							':ultimo' => $data_alteracao
						));

						$this->sistema->logs->adicionar_log_login($dados, 0);

						$usuario = new Usuario_Adm($dados["ID_ADM"]);
						$usuario->carregar($this->sistema->bd);
						$_SESSION["usuario"] = $usuario;
						return -1;
					}
					else
						return 0;
					break;
				}
				case Sistema::INDICACOES:{
					try{
						$usuario = preg_replace('#[^0-9]#','',strip_tags($usuario));

						// Faz a consulta no banco
						$dados = $this->sistema->bd->executar("SELECT NU_ID, NU_ATIVO, NU_CPF, TXT_NOME, TXT_SENHA_TRANSF, TXT_EMAIL, DT_NASCIMENTO, TEL_CEL, TOKEN_CONTA, TXT_SENHA FROM TBL_INDICACOES WHERE NU_CPF = :NU_CPF AND NU_TIPO = 1 AND NU_CLIENTE = :ID", array(
							':NU_CPF' => $usuario,
							':ID' => $this->sistema->indicacoes->id
						), Banco_Dados::FETCH);

						if($this->sistema->bd->quantidade() > 0 & crypt($senha, $dados['TXT_SENHA']) === $dados['TXT_SENHA']){
							if($dados['NU_ATIVO'] == "0"){
								$ativacao = $dados['TOKEN_CONTA'];
								$email = $dados['TXT_EMAIL'];
								$link_at = 'http://'.$this->sistema->indicacoes->dominio.'/?t='.$ativacao;
								$mensagem_email = $this->sistema->indicacoes->vocabulario[9];
								$mensagem_email = str_replace("#LINK#", $link_at, $mensagem_email);
								$this->sistema->enviar_email_indicacao($mensagem_email, "Ative sua Conta", $email, $this->sistema->indicacoes->nome);
								return 2;
							}
							else{
								$usuario = new Usuario_Indicador($dados["NU_ID"]);
								$_SESSION["usuario"] = $usuario;
								return -1;
							}
						}
						else{
							return 1;
						}
					}
					catch(Exception $e){
						return 0;
					}
				}
				case Sistema::GOOGLE_DRIVE:{
					try{
						// Faz a consulta no banco
						$dados = $this->sistema->bd->executar("SELECT * FROM TBL_GDRIVE_USUARIOS WHERE TXT_LOGIN = :login AND ID_FK = :ID", array(
							':login' => $usuario,
							':ID' => $this->sistema->drive->id
						), Banco_Dados::FETCH);

						if($this->sistema->bd->quantidade() > 0 & crypt($senha, $dados['TXT_SENHA']) === $dados['TXT_SENHA']){
							$timestamp = time();
							date_default_timezone_set('America/Sao_Paulo');
							$data_alteracao = date('Y-m-d H:i:s', $timestamp);
							$this->sistema->bd->executar("UPDATE TBL_GDRIVE_USUARIOS SET DT_ULTIMO_LOGIN = :ultimo WHERE TXT_LOGIN = :login AND ID_FK = :ID", array(
								':login' => $usuario,
								':ID' => $this->sistema->drive->id,
								':ultimo' => $data_alteracao
							));

							$usuario = new Usuario_Arquivos($dados["NU_ID"]);
							$_SESSION["usuario"] = $usuario;
							return -1;
						}
						else{
							return 1;
						}
					}
					catch(Exception $e){
						return 0;
					}
				}
			}
		}
		catch(Exception $e){
			return 1;
		}
	}

	/* 
		Método que faz a tentativa de login para o subusuário e senha fornecidos.
		Após finalizar o processo, ele retorna um número que diz se a operação
		foi um sucesso, podendo ser:

		-1: sucesso
		0: usuário ou senha inválidos
		1: erro no banco dados/código
	*/
	function logar_subusuario($usuario, $senha){
		try{
			$params = array(':TXT_LOGIN' => $usuario);
			$dados = $this->sistema->bd->executar("SELECT * FROM TBL_SUBUSUARIOS WHERE TXT_LOGIN = :TXT_LOGIN", $params, Banco_Dados::FETCH);

			if($this->sistema->bd->quantidade() == 0){ // O nome de usuário não foi encontrado
				return 0;
			}

			// Inicializamos essa flag que indica se a criptografia da senha é antiga (md5) ou a nova (blowfish)
			$antiga = true;
			if(empty($dados['TXT_SENHA_NOVA'])){ // Se esse campo do banco está vazio, quer dizer que a senha é antiga(md5)
				if($dados['TXT_SENHA'] === md5($senha)){ // Verificamos se a senha está correta
					try{
						// Caso a senha esteja correta, convertemos a criptografia da senha para blowfish
						$dados['TXT_SENHA_NOVA'] = Utilitarios::hash_str($senha);
						$params = array(
							':TXT_LOGIN' => $usuario,
							':TXT_SENHA_NOVA' => $dados['TXT_SENHA_NOVA']
						);
						$this->sistema->bd->executar("UPDATE TBL_SUBUSUARIOS SET TXT_SENHA = '', TXT_SENHA_NOVA = :TXT_SENHA_NOVA WHERE TXT_LOGIN = :TXT_LOGIN", $params, Banco_Dados::FETCH);
						$antiga = false;
					}
					catch(Exception $e){ 
						// Se houve qualquer erro na conversão de criptografia, utilizaremos o md5 mesmo
						$antiga = true;
					}
				}
				else{ // A senha não está correta...
					return 0;
				}
			}
			else // O campo do banco que contém a senha em blowfish não está vazio, então devemos usar blowfish e não md5
				$antiga = false;

			// Verificamos se a senha está correta
			$verificada = $antiga ? 
				($dados['TXT_SENHA'] === md5($senha)) :
				(crypt($senha, $dados['TXT_SENHA_NOVA']) === $dados['TXT_SENHA_NOVA']);

			if($verificada){
				$this->sistema->logs->adicionar_log_login($dados, 1);

				$usuario = new Subusuario_Win7($dados['NU_ID']);
				$_SESSION["usuario"] = $usuario;
				return -1;
			}
			else
				return 0;
		}
		catch(Exception $e){
			return 1;
		}
	}

	/* Desloga o usuário atual */
	function deslogar(){
		if($this->logado()){
			if(!$this->sistema->usuario instanceof Usuario_Indicador){
				$this->sistema->logs->adicionar_log_logout();
			}
			session_unset();
			session_destroy();
			$this->inicializar_sessao_php();
		}
	}

	/* Renova a sessao atual, mudando o ID */
	function renovar_sessao(){
		session_regenerate_id();
		$new_sess_id = session_id();
		session_write_close();
		session_id($new_sess_id);
		$this->inicializar_sessao_php();
	}
}
?>