<?
//Constantes de manejo de log
define("LOG_ERROR", "1");
define("LOG_DEBUGGING", "2");
define("LOG_INFORMATION", "3");

define("SYS_BS", "1");
define("SYS_CP", "2");
define("SYS_DI", "3");
define("SYS_SSI", "4");
define("SYS_WS", "5");
define("SYS_TF", "6");
define("SYS_CA", "7");
define("SYS_WB", "8");
define("SYS_SAC", "9");

//date_default_timezone_set('America/Buenos_Aires');

class LogMessages {

	private $mensajes = array();
	private static $nSegundoInicio;

	private static $cSistema = array (	SYS_BS => 	"BROADSOFT",
										SYS_CP => 	"CRITICAL PATH",
										SYS_DI => 	"DETALLE IUNI",
										SYS_SSI => 	"SSI",
										SYS_WS => 	"WEB SERVICE",
										SYS_TF => 	"TENFOLD",
										SYS_CA => 	"CONTROL APP",
										SYS_WB => 	"WEB",
										SYS_SAC => 	"SAC"
										);
	
	private static $mensajes_detalle = array(	0 => "Ok.", 
												1 => "Agarrado por el Gestor de errores",
												2 => "No pudo conectar al Web Service",
												3 => "Finalizado manualmente",
												4 => "Fallo al Ejecutar funcion de package",
												5 => "Consulta vacia",
												6 => "Fallo al Ejecutar la funcion de Web Service",
												7 => "Error de Validacion",
												8 => "Fallo al identificar la relacion"
													);
	
	private static $instance = null;

	private function __construct() {
		return(true);
	}

	public static function getMensajes() {
		$dbase = BaseDatos::NuevaConeccion(ORACLE, DB_SERVER, "ADMIN_IUNI", "ADMIN_IUNI", "wholesale2010");
		$fu_msgs = "PKG_CAP_MENSAJELOG.FU_GET_MENSAJES(". USER_ID .")";
		$lala = $dbase->EjecutarPackage($fu_msgs, 1);
		$mensajes_detalle = array();
		while ($asd = $dbase->FetchArray(1)) {
			$mensajes_detalle[$asd["MENSAJE_ID"]] = array("Desc" => $asd["DESC_MENSAJE"], "TipoID" => $asd["T_MENSAJE_ID"], "Tipo" => $asd["DESC_T_MENSAJE"], "GrupoID" => $asd["G_MENSAJE_ID"], "Grupo" => $asd["DESC_G_MENSAJE"]);
		}

		self::$mensajes_detalle = $mensajes_detalle;
		/*echo "<pre>";
		print_r($mensajes_detalle);
		echo "</pre>";
		die();*/

	}
	
	public static function GetInstance() {
		if (!isset(self::$instance)) {
			$c = __CLASS__;
			self::$instance = new $c;
			//abro el log de archivo
			$log = LogErrorWeekDay::GetLog();
			$log->SetPathLog(LOG_LOCATION);
			$log->SetStartScriptTime(date("c"));
			$log->AddLog(self::$cSistema[SYS_CA] . ": Empieza un nueva corrida de script xd");
			self::$nSegundoInicio = LogMessages::microtime_float();
		}
		return self::$instance;
	}

	public function AddLog($tipo_mensaje, $sistema, $idMensaje, $cDetalle = "", $orden = "", $procesoId = "") {
		//trunco a 1024 q es el maximo q entra
		$cDetalle = substr($cDetalle, 0, 1024);
		//echo "[$tipo_mensaje] [$sistema] [$idMensaje] [$cDetalle]"; die();
		$this->mensajes[$sistema][$tipo_mensaje][] = array($idMensaje => $cDetalle);
	
		$cSistema = self::$cSistema[$sistema];
		$cMensaje = self::$mensajes_detalle[$idMensaje]["Desc"];
		
		$log = LogErrorWeekDay::GetLog();
		$ordenOriginal = $orden;
		$orden = ($orden != "") ? "[" . $orden . "]" : $orden;
		$log->AddLog($cSistema . ": " . $orden . $cMensaje . " - " . $cDetalle, $tipo_mensaje);


		$dbase = BaseDatos::NuevaConeccion(ORACLE, DB_SERVER, "ADMIN_IUNI", "ADMIN_IUNI", "wholesale2010");

		$sql_LOG = "PKG_CAP_LOG.FU_LOG_INS(". USER_ID .", $sistema, $idMensaje, :cDetalle )";
		$lala = $dbase->EjecutarPackageLog($sql_LOG, 7, $cDetalle);


		$asd = $dbase->FetchArray(7);
		$dbase->FreeResultset(7);
		//var_dump($asd);
		if ( (!is_array($asd)) || (( isset($asd["SQLCODE_ERROR"])) && ($asd["SQLCODE_ERROR"] != "200")) ) {
			$desc = (is_array($asd)) ? "[SQLCODE_ERROR] => " . $asd["SQLCODE_ERROR"] . " [FUNCION] => " . $asd["FUNCION"] . " [SQLERRM_ERROR] => " . $asd["SQLERRM_ERROR"] : "";
			$log->AddLog(self::$cSistema[SYS_CA] . ": No pudo escribir en el log de database", LOG_ERROR);
			set_error_handler("miGestorErrores");
			trigger_error("PKG_CAP_LOG.FU_LOG_INS", E_USER_WARNING);
		} else {
			if ($orden != "") {
				$log_id = $asd["LASTID"];
				$sql_LOGORDEN = "PKG_CAP_ORDENESLOG.FU_ORDENESLOG_INS(". USER_ID .", $ordenOriginal, $log_id)";
				$lala = $dbase->EjecutarPackage($sql_LOGORDEN, 8);
			} else {
				if ($procesoId != "") {
					$log_id = $asd["LASTID"];
					$sql_LOGORDEN = "PKG_CAP_PROCESOLOG.FU_PROCESOLOG_INS(". USER_ID .", $procesoId, $log_id)";
					$lala = $dbase->EjecutarPackage($sql_LOGORDEN, 8);
				}
			}
		}



	}

	public function closeLog() {
		//echo "close log!!!"; 
		/*<pre>";
		print_r($this->mensajes);
		echo "</pre>";*/

		$aCorreos = array();
		if (is_array($this->mensajes) && count($this->mensajes) > 0) { 
			//echo "[xd]";
			foreach ($this->mensajes as $sistema => $aMensajes) {
				//Pido INFO de a quien tengo q mandarle el mail...
				//$to_mail = "fbernoldi@iplan.com.ar"; //
				
				//Seteo los datos del mail
				//$logM = LogEmail::GetMail();
				//$logM->setEmailData(FROM_MAIL, $to_mail);
				//echo "[asd]";
				foreach ($aMensajes as $cTipoMensaje => $aMensaje) {
					//echo "[$cTipoMensaje]";
					switch ($cTipoMensaje) {
						case LOG_INFORMATION:
						case LOG_DEBUGGING:
							//break;
						case LOG_ERROR:
							//Agrego al contenido del mail
							foreach ($aMensaje as $mensaje) {
								while ($idMensaje = key($mensaje)) {
									//$idMensaje = $key;
									$cMensaje = $mensaje[$idMensaje];
									unset($mensaje[$idMensaje]);
									//Tomo de Base de datos el mail a quien mandar
									//$cMensaje
									//$to_mail = "fbernoldi@iplan.com.ar";
									
									$dbase = BaseDatos::NuevaConeccion(ORACLE, DB_SERVER, "ADMIN_IUNI", "ADMIN_IUNI", "wholesale2010");
									$sql_contact = "PKG_CAP_CONTACTOEMERGENCIA.FU_CONTACTOEMERGENCIA_SEL(". USER_ID .", $idMensaje, $sistema)"; //9 cancelado

									$lala = $dbase->EjecutarPackage($sql_contact, 8);
									$asd = $dbase->FetchArray(8);
									$dbase->FreeResultset(8);

									/*if ( (!is_array($asd)) || (( isset($asd["SQLCODE_ERROR"]) && ($asd["SQLCODE_ERROR"] != "200")) ) {
										$desc = (is_array($asd)) ? "[SQLCODE_ERROR] => " . $asd["SQLCODE_ERROR"] . " [FUNCION] => " . $asd["FUNCION"] . " [SQLERRM_ERROR] => " . $asd["SQLERRM_ERROR"] : "";
										//$log->AddLog(self::$cSistema[SYS_CA] . ": No pudo escribir en el log de database", LOG_ERROR);
										//set_error_handler("miGestorErrores");
										//trigger_error("PKG_CAP_LOG.FU_LOG_INS", E_USER_WARNING);
									}*//* else {
										
									}*/
									$aContactos = explode(',', $asd['CONTACTO']);
									foreach ($aContactos as $cContactin) {
										$aCorreos[$cContactin][] = "Sistema: " . self::$cSistema[$sistema]. "; Error: " . $asd['DESCRIPCION'] . "; Descripcion: $cMensaje";
									}
								}
							}
							break;
					}
				}
				
				//Envio el mail xd
				
			}
		}
		//print_r($aCorreos); die();
		$nSegundoFin = LogMessages::microtime_float();
		$nElapsed = ($nSegundoFin - self::$nSegundoInicio);

		$log = LogErrorWeekDay::GetLog();
		$log->AddLog(self::$cSistema[SYS_CA] . ": Tiempo de Ejecucion: " . number_format($nElapsed/60, 2, ",", ".") ." minutos/s", LOG_INFORMATION);
		$log->AddLog(self::$cSistema[SYS_CA] . ": Fin", LOG_INFORMATION);


		//ciclar x la cantidad de mails que tengo q enviar

		
		if ((is_array($aCorreos)) && (count($aCorreos) > 0)) {
			$logM = LogEmail::GetMail();
			foreach ($aCorreos as $destinatario => $correo) {
				$logM->setEmailData(FROM_MAIL, $destinatario);
				$logM->setDatosCompletos(null);
				foreach ($correo as $dato) {
					$logM->AddLog($dato);
				}
				if ($logM->getTieneDatos()) {
					$logM->setSubject("IUNI WHOLESALE PROVISIONING - Fallo en el Script");
					$logM->setContenidoCuerpo("Sr. Administrador,\r\n\r\nAbra el adjunto del correo para ver el detalle de los errores de importación.\r\n\r\nAtte. Provisioning IUNI Wholesale\r\n");
					$logM->send();
				}
			}
		}

		/*$logM = LogEmail::GetMail();
		$logM->setEmailData(FROM_MAIL, TO_MAIL);
		if ($logM->getTieneDatos()) {
			//errores!
			$logM->setSubject("IUNI WHOLESALE PROVISIONING - Fallo en el Script");

			$logM->setContenidoCuerpo("Sr. Administrador,\r\n\r\nAbra el adjunto del correo para ver el detalle de los errores de importación.\r\n\r\nAtte. Provisioning IUNI Wholesale\r\n");
		} else {
			$logM->setSubject("IUNI WHOLESALE PROVISIONING - Todo en orden :D");
			$logM->setContenidoCuerpo("Sr. Administrador,\r\n\r\n¡Enhorabuena!, El proceso de provisioning se ha realizado con éxito.\r\n\r\nTiempo de ejecución: ".number_format($nElapsed/60, 2, ",", ".")." minuto/s.\r\n\r\nAtte. Provisioning IUNI Wholesale\r\n");
			//todo okey xdd
		}
		$logM->send();*/
	}

	private static function microtime_float() {
	    list($useg, $seg) = explode(" ", microtime());
	    return ((float)$useg + (float)$seg);
	}
}

/* Clases para logueo de eventos en Archivo */
class LogError {
	private $instancia = null;
	private $rFileLog = null;
	private $bEstado = false;
	
	public function __construct($cArchivoLog, $bNewlog = false) {
		$this->rFileLog = fopen($cArchivoLog, ($bNewlog) ? "w" : "a");
		$this->bEstado = ($this->rFileLog) ? true : false;
		return ($this->bEstado);
	}

	/* no se puede clonar xd */
	public function __clone() {
		return(false);
	}
	
	public function AddLog($cStr) {
		$bOk = false;
		$cStr = str_replace("\r", "", $cStr);
		$cStr = str_replace("\n", "", $cStr);
		$cStr = str_replace("\t", "", $cStr);
	  	if ($this->bEstado)
			$bOk = fwrite($this->rFileLog, $cStr . "\r\n");
		return ($bOk);
	}
	
	public function CloseLog() {
		$bOk = fclose($this->rFileLog);
		if ($bOk)
			$this->bEstado = false;
		return ($bOk);
	}
	
	public function __destruct() {
		return ($this->CloseLog());
	}
}


class LogErrorWeekDay {
	private $_rFileLog = null;
	private $_diaActual = "";
	private $_cPathLog = "";
	private static $instance = null;
	private $_start_time = null;
	
	public function SetStartScriptTime($cFullDateTime) {
	  	$ok = false;
		if (self::$instance) {
			$this->_start_time = $cFullDateTime;
			$ok = true;
		}
		return($ok);
	}
	
	private function __construct() {
		//return ($this->bEstado);
		return(true);
	}
	
	public function SetPathLog($cPathLog) {
		//return ($this->bEstado);
		$this->_cPathLog = $cPathLog;
		return($this->_cPathLog == true);
	}
	
	public static function GetLog() {
		if (!isset(self::$instance)) {
			$c = __CLASS__;
			self::$instance = new $c();
		}
		return self::$instance;
	}
	
	/* no se puede clonar xd */
	public function __clone() {
		return(false);
	}
	
	/* funcion para agregar datos al archivo de log que corresponda */
	public function AddLog($cStr, $tipo_error = LOG_INFORMATION) {
		$bOk = false;
		$LogUsar = $this->_cPathLog . LOG_FILE_NAME . "." . date("D").".log";
		if (!file_exists($LogUsar))
			touch($LogUsar);
		$rTemp = fopen($LogUsar, "r");
		$cUltimaLinea = LogErrorWeekDay::seek_last_line($rTemp);
		$UltimaFechaLog = substr($cUltimaLinea, 0, 25);
		$dateViejo = new DateTime($UltimaFechaLog);
		$dateNuevo = new DateTime($this->_start_time);
		$diasDiferencia = $dateViejo->format("Ymd") - $dateNuevo->format("Ymd");
		fclose($rTemp);
		if ($diasDiferencia < 0) {
		  	//el log es viejo y hay q pisarlo o esta vacio
			$accion = "w";
			$this->_diaActual = date("D");
		} else {
		  	//el log es de la fecha actual
			$accion = "a";
		}
		$this->_rFileLog = fopen($LogUsar,  $accion);
		
		switch ($tipo_error) {
			case LOG_INFORMATION:
				$cPrefijo = "[INFO]";
			break;
			case LOG_DEBUGGING:
				$cPrefijo = "[DEBUG]";
			break;
			case LOG_ERROR:
				$cPrefijo = "[ERROR]";
			break;
			
			default:
				$cPrefijo = "";
			break;
		}

		$cStr = str_replace("\r", "", $cStr);
		$cStr = str_replace("\n", "", $cStr);
		$cStr = str_replace("\t", "", $cStr);
	  	if ($this->_rFileLog) {
			$bOk = fwrite($this->_rFileLog, date("c") . " " . $cPrefijo . $cStr . "\r\n");
			fclose($this->_rFileLog);
		} else {
			echo "\r\nNo se puede abrir el archivo de log, chequee ser root o ser lo suficientemente groso como para crear y modificar archivos en donde tenes los log xd\r\n";
		  	die();//!!!
		}
		return ($bOk);
	}
	/*
	funcion auxiliar para levantar la ultima linea del log, considerando que todas las lineas terminan en \r\n

	*/
	private static function seek_last_line($r) {
	  	$ultimaLinea = false;
	  	$sigo_buscando = true;
		$ok = fseek($r, -2, SEEK_END);
		if (!$ok) {
			$xd = fread($r, 2);
		  	if($xd == "\r\n") {
				$i = -3;
				while((!fseek($r, $i, SEEK_END)) && ($sigo_buscando)) {
					$tmprd = fread($r, 2);
					$ultimaPosicion = ftell($r);
					$i--;
					if ($tmprd == "\r\n") {
						$sigo_buscando = false;
					}
				}
				if (!$sigo_buscando) {
					fseek($r, $ultimaPosicion, SEEK_SET);
					$ultimaLinea = fgets($r);
				} else {
					//no encontro una linea completa o sea \r\n LineaCompleta lala \r\n
				}
			} else {
				//no termina en \r\n;
			}
			//vuelvo al principio xd
			fseek($r, 0, SEEK_SET);
		} else {
		  	//el archivo tiene menos de 2 bytes, que cagada no?
		}
		return($ultimaLinea);
	}
	
}





class LogEmail {
	/* variables privadas xd */
	//private $instancia = null;
	private $bEstado = false;
	private $filename = "";
	private $data = "";
	private $from = "";
	private $to = "";
	private $subject = "";
	private $contenido_cuerpo = "";
	private $tieneDatos = false;
	private static $instance;
	
	/* Funciones de asignacion de datos para el envio de correo */
	public function setFrom($from) {
		$this->from = $from;
		return(true);
	}
	
	public function setTo($to) {
		$this->to = $to;
		return(true);
	}
	
	public function setSubject($subject) {
		$this->subject = $subject;
		return(true);
	}
	
	public function setFilename($filename) {
		$this->filename = $filename;
		return(true);
	}
	
	public function setDatosCompletos($data) {
		$this->data = $data;
		return(true);
	}
	
	public function setContenidoCuerpo($contenido_cuerpo) {
		$this->contenido_cuerpo = $contenido_cuerpo;
		return(true);
	}
	
	/* Funciones para leer los datos para el envio de correo */
	public function getFrom() {
		return($this->from);
	}
	
	public function getTo() {
		return($this->to);
	}
	
	public function getSubject() {
		return($this->subject);
	}
	
	public function getFilename() {
		return($this->filename);
	}
	
	public function getEstadoEnviado() {
		return($this->bEstado);
	}
	
	public function getTieneDatos() {
		return($this->tieneDatos);
	}
	
	/* Funcion para levantar un archivo en el filesystem para mandar por mail */
	public function importFile($filename_fisico) {
		$this->filename = basename($filename_fisico);
		$this->data = file_get_contents($filename_fisico);
		$this->tieneDatos = ($this->data !== false);
		return($this->tieneDatos);
	}
	
	/* Constructor privado :) singleton rlz
	
	*/
	
	private function __construct() {
		/*if ($this->instancia) {
			return($this->instancia);
		} else {
			$this->instancia = $this;
		}*/
		return (true);
	}
	
	/* Para poner las cosas de una
	
	from: direccion de origen del correo
	to: direccion de destino del correo
	subject: asunto del correo
	filename_fisico: opcional archivo fisico
	
	si esta definido filename_fisico, no le da bola a nombre_attach
	
	*/
	
	public function setEmailData($from, $to, $subject = "", $nombre_attach = false, $filename_fisico = false) {
		$this->from = $from;
		$this->to = $to;
		$this->subject = $subject;
		$this->bEstado = false;
		$this->filename = $nombre_attach;
		if ($filename_fisico)
			$bSubidoCorrecto = $this->importFile($filename_fisico);
		
		return ((isset($bSubidoCorrecto)) ? $bSubidoCorrecto : true);
	}
	
	/* Funcion que se usa para obtener la instancia */
	public static function GetMail($from = "", $to = "", $subject = "", $nombre_attach = false, $filename_fisico = false) {
		if (!isset(self::$instance)) {
			$c = __CLASS__;
			self::$instance = new $c;
		}
		return self::$instance;
	}
	
	/* no se puede clonar xd */
	public function __clone() {
		return(false);
	}
	
	/* agrega al contendido del attachment el string cStr */
	public function AddLog($cStr) {
		$cStr = str_replace("\r", "", $cStr);
		$cStr = str_replace("\n", "", $cStr);
		$cStr = str_replace("\t", "", $cStr);
		$this->data .= "(". date("c"). ") " . $cStr . "\r\n";
		$this->tieneDatos = true;
		return (true);
	}
	
	/* limpia las variables de la clase para liberar memoria xd */
	public function CloseLog() {
		unset($this->data);
		unset($this->subject);
		unset($this->from);
		unset($this->to);
		unset($this->filename);
		unset($this->bEstado);
		return (true);
	}
	
	/* pum! soy un destructor */
	public function __destruct() {
		return ($this->CloseLog());
	}
	
	/* aca esta la posta, te manda el mail que preparaste */
	public function send() {
	  	if ((!$this->to)||(!$this->from)||(!$this->subject)) {
	  		$this->bEstado = false;
	  	} else {
	  		
			$headers="";
			$headers.="From:$this->from";
			$message="";
			if ($this->data) {
			  	$this->filename = (!$this->filename) ? "archivo" : $this->filename;
				$fileatt_type = "text/plain";
				$semi_rand = md5(time());
				$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
		
				$headers .= "\nMIME-Version: 1.0\n" .
							"Content-Type: multipart/mixed;\n" .
							" boundary=\"{$mime_boundary}\"";
		
				$message =	"This is a multi-part message in MIME format.\n\n" .
							"--{$mime_boundary}\n" .
							"Content-Type: text/plain; charset=\"UTF-8\"\n" .
							"Content-Transfer-Encoding: 7bit\n\n" .
							$this->contenido_cuerpo .
		        $message . "\n\n";
				
				$data = chunk_split(base64_encode($this->data));
				
				$message .= "--{$mime_boundary}\n" .
							"Content-Type: {$fileatt_type};\n" .
							" name=\"{$this->filename}\"\n" .
							"Content-Disposition: attachment;\n" .
							" filename=\"{$this->filename}\"\n" .
							"Content-Transfer-Encoding: base64\n\n" .
							$data . "\n\n" . "--{$mime_boundary}--\n";
			} else {
				$message = $this->contenido_cuerpo;
			}
			
			$this->bEstado = mail($this->to, $this->subject, $message, $headers);
	        /*
	        echo "To: $this->to\r\n";
	        echo "Subject: $this->subject\r\n";
	        echo "from: $this->from\r\n";
	        echo "message: $message\r\n";
	        echo "contenido_cuerpo: $this->contenido_cuerpo\r\n";
			$this->bEstado = true;*/
		}
		return($this->bEstado);
	}
}

function des_cgpear($cgp) {
	$tenfold = "";
	
	$tenfold = ltrim(substr($cgp, 0, -1), "0");

	return ($tenfold);
}

/*function get_cgp( $client_number )
{
  //Get a 6-digit customer code with leading 0s
  $whit_mask = str_pad($client_number, 6, '0', STR_PAD_LEFT);

  // Extrae todos los digitos
  for($i=0; $i < strlen($whit_mask); $i++)
          $barcode[] = $whit_mask[$i];

  // Se queda con la parte entera del resultado
  list($calc, ) = explode('.',( $barcode[0]*1 + $barcode[1]*3 +
    $barcode[2]*5 + $barcode[3]*7 + $barcode[4]*9 + $barcode[5]*3 ) / 2);

  // Extrae el ultimo digito
  $verificationDigit = substr($calc,-1,1);

  // Devuelve el numero de cliente (con los ceros) mas el digito de verificacion
  return trim($whit_mask.$verificationDigit);
}
*/

class RespuestasTenfold {

	private static $instance;

	private $aMensajes = array();

	private function __construct() {
		return (true);
	}

	public static function GetInstance() {
		if (!isset(self::$instance)) {
			$c = __CLASS__;
			self::$instance = new $c;
		}
		return self::$instance;
	}

	/* no se puede clonar xd */
	public function __clone() {
		return(false);
	}

	public function AddMensaje($cMensaje) {
		$this->aMensajes[] = $cMensaje;
	}

	public function GetMensajes() {
		return (implode("|", array_unique($this->aMensajes)));
	}

	public function ClearMensajes() {
		$this->aMensajes = array();
	}

}

?>
