<?php

/**
 * Module qui gère l'envoi et la reception de message
 * 
 * @author Olivier Arteau
 */

class Message implements Module {
	private $resultat = array();
	
	public function executerCommande(array $param, StatusObject $status) {
		// On ne fait rien si c'est cancellé //
		if (get_class($status) == 'CommandStatus' && $status->isCancel()) {
    		$this->onStatusChange($param, $status);
    		return PAFServer::$NO_ACTION_TAKEN;
    	}
		
		// Vérification commune //
		$utilisateur = Session::getUtilisateurCourrant();
		
		if ($utilisateur == null) {
			$this->resultat = array(
    			'resultat' => 'false',
    			'message' => 'Utilisateur non connecté'
    		);
    		
    		if (get_class($status) != 'CommandStatus')
    			$status = new CommandStatus();
    		$status->addMessage('Utilisateur non connecté');
    		$status->cancel();
    		
    		return $status;
		}
		
		switch ($param['cmd']) {
			case 'msg' :
				return $this->gestionMessage($param, $status);
			case 'privmsg' :
				return $this->gestionMessagePrive($param, $status);
			case 'getmsg' : 
				return $this->gestionGetMessage($param, $status);
		}
		
		return PAFServer::$NO_ACTION_TAKEN;
	}
	
	private function gestionMessage(array $param, StatusObject $status) {
		// Vérifie s'il manque des paramètres et s'ils sont valides //
		$filter = array(
			'salle' => '{EN_Alphabet}',
			'data' => '/^.*$/'
		);
		if (!FormControl::checkForm($param, $filter)) {
    		$this->resultat = array(
    			'resultat' => 'false',
    			'message' => 'Paramètre manquant'
    		);
    		
    		if (get_class($status) != 'CommandStatus')
    			$status = new CommandStatus();
    		$status->addMessage('Paramètre manquant');
    		$status->cancel();
    		
    		return $status;
		}
		
		$utilisateur = Session::getUtilisateurCourrant();
		
		// S'il n'est pas dans la salle, on retourne un message d'erreur //
		if (!$utilisateur->isInRoom($param['salle'])) {
    		$this->resultat = array(
    			'resultat' => 'false',
    			'message' => 'Vous devez être dans la salle pour pouvoir envoyer des messages dans celle-ci.'
    		);
    		
    		if (get_class($status) != 'CommandStatus')
    			$status = new CommandStatus();
    		$status->addMessage('Vous devez être dans la salle pour pouvoir envoyer des messages dans celle-ci.');
    		$status->cancel();
    		
    		return $status;
		}
		
		// Définit temporairement la requête comme correcte //
		$this->resultat = array(
    		'resultat' => 'true',
    		'message' => 'Message ajouté'
    	);
	
		return PAFServer::$NO_ACTION_TAKEN;
	}
	
	private function gestionMessagePrive(array $param, StatusObject $status) {
		// Vérifie s'il manque des paramètres //
		if (!isset($param['user']) || !isset($param['data'])) {
    		$this->resultat = array(
    			'resultat' => 'false',
    			'message' => 'Paramètre manquant'
    		);
    		
    		if (get_class($status) != 'CommandStatus')
    			$status = new CommandStatus();
    		$status->addMessage('Paramètre manquant');
    		$status->cancel();
    		
    		return $status;
		}
		
		$isExisting = true;
		try {
			$usr = new Utilisateur($param['user']);
			$usr->getID();
		} catch (Exception $e) {
			$isExisting = false;
			$this->resultat = array(
    			'resultat' => 'false',
    			'message' => 'Utilisateur inexistant'
    		);
    		
    		if (get_class($status) != 'CommandStatus')
    			$status = new CommandStatus();
    		$status->addMessage('Paramètre manquant');
    		$status->cancel();
    		
    		return $status;
		}
		
		// Définit temporairement la requête comme correcte // 
		$this->resultat = array(
    			'resultat' => 'true',
    			'message' => 'Message envoyé'
    	);
		
		return PAFServer::$NO_ACTION_TAKEN;
	}
	
	private function gestionGetMessage (array $param, StatusObject $status) {
		$utilisateur = Session::getUtilisateurCourrant();
		$lstSalles = $utilisateur->getSallesConnectes();
		$idSalles = array();
		
		$sqlPart = '';
		if (count($lstSalles) > 0) {
			$sqlPart .= '(`toType` = \'salle\' AND (';
			$sqlPart .= '`to` = ?';
			array_push($idSalles, $lstSalles[0]->getNom());
			
			for ($i=1; $i<count($lstSalles); $i++) {
				$sqlPart .= ' OR `to` = ?';
				array_push($idSalles, $lstSalles[$i]->getNom());
			}
			
			$sqlPart .= ')) OR ';
		}
		
		$bd = BDConnexion::getBDConnexion();
		$sql = 'SELECT `data`,`type`,`from`,`to` FROM messages WHERE `timestamp` > ? AND (' . $sqlPart . '(`toType` = \'user\' AND `to`=?))';
		
		$microtime = microtime(true)*1000;
		
		$parametres = array_merge(
			array(Session::getValeur('lastMessageGet', $microtime)),
			$idSalles,
			array($utilisateur->getNom())
		);
		
		$resultat = $bd->execQuerySelect($sql, $parametres);
		$this->resultat = $resultat;
		Session::setValeur('lastMessageGet', $microtime);
		return PAFServer::$NO_ACTION_TAKEN;
	}
	
	public function getCommandesEnregistre() {
		return array('msg', 'privmsg', 'getmsg');
	}
	
	public function onStatusChange(array $param, StatusObject $status) {
		if (get_class($status) == 'CommandStatus' && $status->isCancel()) {
			$this->resultat = array (
				'resultat' => 'false',
				'message' => $status->toString()
			);
		}
	}
	
	public function finalize(array $param, StatusObject $status) {
   		if ((get_class($status) == 'CommandStatus' && !$status->isCancel()) || $status == PAFServer::$NO_ACTION_TAKEN) {
	   		if (isset($param['data']))
	   			$param['data'] = htmlentities($param['data']);
	   		
	   		switch ($param['cmd']) {
		   		case 'msg' :
		   			$utilisateur = Session::getUtilisateurCourrant();
		   			$microtime = microtime(true)*1000;
		   			
			   		// Ajoute le message //
					$db = BDConnexion::getBdConnexion();
					$sql = 'INSERT INTO messages (`type`,`data`,`from`,`to`,`timestamp`,`toType`) VALUES (?,?,?,?,?,?)';
					$parametre = array('msg', $param['data'], $utilisateur->getNom(), $param['salle'], $microtime, 'salle');
					$db->execQuery($sql, $parametre);
					break;
				case 'privmsg' :
					$utilisateur = Session::getUtilisateurCourrant();
		   			$microtime = microtime(true)*1000;
		   			
		   			// Ajoute le message //
					$db = BDConnexion::getBdConnexion();
					$sql = 'INSERT INTO messages (`type`,`data`,`from`,`to`,`timestamp`,`toType`) VALUES (?,?,?,?,?,?)';
					$parametre = array('privmsg', $param['data'], $utilisateur->getNom(), $param['user'], $microtime, 'user');
					$db->execQuery($sql, $parametre);
					break;
	   		}
   		}
   		
   		JSONOutput::output($this->resultat);
   	}
}

PAFServer::getInstance()->enregistrerModule(new Message());
?>