<?php
require_once (__DIR__ . '/../../../sistemawin7lib/vendor/autoload.php');
require_once(__DIR__ . "/../Banco_Dados.php");
use PHPMailer\PHPMailer\PHPMailer;

/* Essa função marca o processo como não executando caso ocorra algum erro. */
function erro_verificacao_emails($errno, $errstr, $errfile, $errline){
	$bd = new Banco_Dados(false);
	$bd->executar("UPDATE TBL_PROCESSO_EMAIL SET NU_EXECUTANDO = 0 WHERE NU_ID = 1");
}
$old_error_handler = set_error_handler("erro_verificacao_emails");

/* Garante que o script vai rodar indefinidamente */
ignore_user_abort(true);
set_time_limit(0);
error_reporting(-1);

try{
	// Obtém os dados do processo de envio de email
	$bd = new Banco_Dados(false);
	$sql = "SELECT * FROM TBL_PROCESSO_EMAIL WHERE NU_ID = 1";
	$resultado = $bd->executar($sql, array(), Banco_Dados::FETCH);
	$ultima_execucao = strtotime($resultado['ULTIMA_EXECUCAO']);
	$tempo_atual = time();

	if($tempo_atual - $ultima_execucao <= 600 && $resultado['NU_EXECUTANDO'] == "1"){
		exit;
	}

	$sql = "UPDATE TBL_PROCESSO_EMAIL SET NU_EXECUTANDO = 1 WHERE NU_ID = 1";
	$bd->executar($sql, array(), Banco_Dados::FETCH);

	while(true){
		/* Verifica se o processo não é forçado a parar*/
		$sql = "SELECT * FROM TBL_PROCESSO_EMAIL WHERE NU_ID = 1";
		$resultado = $bd->executar($sql, array(), Banco_Dados::FETCH);
		if($resultado['NU_PARAR'] == "1" || $resultado['NU_EXECUTANDO'] == "0"){
			break;
		}

		/* Atualiza a data de última execução do processo */
		$now = date("Y-m-d H:i:s", time());
		$sql = "UPDATE TBL_PROCESSO_EMAIL SET ULTIMA_EXECUCAO = :execucao WHERE NU_ID = 1";
		$bd->executar($sql, array(":execucao" => $now));

		/* Obtém todos os emails pendentes*/
		$sql = "SELECT * FROM TBL_ENVIO_EMAIL WHERE NU_STATUS = 0 OR NU_STATUS = 4";
		$resultado = $bd->executar($sql, array(), Banco_Dados::FETCH_ALL);

		/* Itera por todos os emails pendentes*/
		foreach($resultado as $envio){
			$mail = new PHPMailer();
			$mail->CharSet = 'UTF-8';
			$mail->Subject = $envio['TXT_ASSUNTO'];
			$mail->msgHTML($envio['TXT_MENSAGEM']);
			$mail->isHTML(true);
			$mail->isSMTP(true);
			$mail->Mailer = "smtp";
			$mail->SMTPSecure = "tls";
			$mail->SMTPAuth = true;
			$mail->setFrom($envio['TXT_EMAIL'], $envio['TXT_NOME']);

			/* Adiciona todos os destinatários */
			if(!empty($envio['TXT_DESTINATARIOS'])){
				$destinatarios = explode(" |$| ", $envio['TXT_DESTINATARIOS']);
				if($destinatarios == false)
					continue;
				$qtd_destinatarios = count($destinatarios);
				if($qtd_destinatarios % 2 == 1)
					continue;
				for($i = 0; $i < $qtd_destinatarios / 2; $i++){
					$mail->AddAddress($destinatarios[$i+$qtd_destinatarios / 2], $destinatarios[$i]);
				}
			}
			/* Se não tiver destinatários, pula esse envio*/
			else{
				continue;
			}
			
			/* Adiciona as cópias ocultas */
			if(!empty($envio['TXT_COPIAS_OCULTAS'])){
				$ocultas = explode(" |$| ", $envio['TXT_COPIAS_OCULTAS']);
				if($ocultas != false){
					$qtd_ocultas = count($ocultas);
					if($qtd_ocultas % 2 != 1){
						for($i = 0; $i < $qtd_ocultas / 2; $i++){
							$mail->addBCC($ocultas[$i+$qtd_ocultas / 2], $ocultas[$i]);
						}
					}
				}
			}

			/* Adiciona o anexo, caso possua */
			if($envio['NU_ATIVAR_ANEXO'] == "1"){
				$mail->addStringAttachment($envio['TXT_ANEXO'], $envio['TXT_NOME_ANEXO']);
			}

			/* Obtém o tipo do email */
			$tipo = intval($envio['NU_TIPO']);
			$status = intval($envio['NU_STATUS']);

			/* Faz o envio do email, dependendo de seu tipo*/
			switch($tipo){
				case 0:
				case 1:
				case 2:
					$mail->Port = 2587;
					$mail->Host = 'email-smtp.us-west-1.amazonaws.com';

					// AUTENTICACAO GERADA DE ACORDO COM AWS4 (Amazon Signature Version 4)
					$mail->Username = "AKIASDZFQZNOH2BXRJ6C";
					$mail->Password = "BKSDMWy7gva5Ia7h2juHoxNYzfua037WW1RFPgD2Z08J";

					/* Caso email tenha sido enviado com sucesso, marca ele como enviado*/
					if($mail -> Send()){
						$sql = "UPDATE TBL_ENVIO_EMAIL SET NU_STATUS = 1 WHERE NU_ID = :id";
						$bd->executar($sql, array(":id" => $envio['NU_ID']));
					}
					else{
						/* Arquiva ou marca email como não enviado, dependendo do status */
						$sql = ($status == 0 ? 
							"UPDATE TBL_ENVIO_EMAIL SET NU_STATUS = 2, TXT_ERRO = :erro WHERE NU_ID = :id": 
							"UPDATE TBL_ENVIO_EMAIL SET NU_STATUS = 3, TXT_ERRO = :erro WHERE NU_ID = :id");
						$bd->executar($sql, array(
							":id" => $envio['NU_ID'],
							":erro" => $mail->ErrorInfo
						));
					}
					break;
			}

		}

		/* Faz o script dormir por 0,5 segundo */
		usleep(500000);

		/* Obtém a data de execução */
		$sql = "SELECT * FROM TBL_PROCESSO_EMAIL WHERE NU_ID = 1";
		$resultado = $bd->executar($sql, array(), Banco_Dados::FETCH);
		$ultima_execucao = $resultado['ULTIMA_EXECUCAO'];

		/* Caso a última data de execução não bata, é porque existe outro processo rodando.
		   Ocorre, portanto, que o script atual deve ser parado */
		if($ultima_execucao != $now){
			break;
		}
	}
	
	/* Caso o loop while tenha sido finalizado, marca o processo como não executando */
	$sql = "UPDATE TBL_PROCESSO_EMAIL SET NU_EXECUTANDO = 0 WHERE NU_ID = 1";
	$bd->executar($sql, array(), Banco_Dados::FETCH);
}
catch(Exception $e){
	/* Caso ocorra algum erro, marca o processo como não executando */
	$bd = new Banco_Dados(false);
	$sql = "UPDATE TBL_PROCESSO_EMAIL SET NU_EXECUTANDO = 0 WHERE NU_ID = 1";
	$bd->executar($sql, array());
}
?>