package q02b.exe.utils;



import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;

import es.ejie.frmk.infraestructura.traza.Q70Traza;



import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.ArrayList;

import java.util.Date;

import java.util.Properties;

import java.util.Vector;



import javax.mail.Flags;

import javax.mail.Folder;

import javax.mail.Message;

import javax.mail.Multipart;

import javax.mail.Part;

import javax.mail.Store;

import javax.mail.Session;

import javax.mail.internet.InternetAddress;

import javax.mail.MessagingException;



import es.ejie.frmk.Q70Factoria;



//import es.ejie.frmk.infraestructura.internacionalizacion.Q70GestorMensajesi18n;

import es.ejie.frmk.infraestructura.mail.Q70MailEnvelope;

import es.ejie.frmk.infraestructura.mail.Q70MailFile;

import es.ejie.frmk.infraestructura.mail.Q70MailMessage;

import es.ejie.frmk.infraestructura.mail.Q70MailUser;



import es.ejie.frmk.listeners.base.Q70ListenerUtils;



import q02b.exe.comun.valueobjects.Q02bMessage;

import q02b.exe.comun.valueobjects.Q02bAttachment;



/**

 * Clase que obtiene el número interno de un elemento a partir de si código

 * 

 * @author leire.uriarte

 * @author Javier.cruz

 *

 */

public class Q02bMailUtils{

	

	//Variable con el JNDI del datasource

	 protected static String Q02_JNDI_DATASOURCE = Q70ListenerUtils.getApplicationProperty("S99bNILocator",null,"Q02_JNDI_DATASOURCE");

	 //Variable para las trazas

	 private static Q70Traza tr = Q70Traza.getSingleton();

	 private final static String COMPONENTE   =  "S99bMailUtils";

	 //Atributos básicos del mensaje

	 private String 			subject				= null;

	 private String 			body				= null;

	 private String 			remitente 			= null;

	 private ArrayList 			listaDestinatarios 	= null;

	 //Variable que contiene los ficheros adjuntos a enviar

	 private Q02bAttachment[] 	attachment			= null;

	 //Variable que se utiliza para insertar el mensaje LOPD en el idioma correcto

	 private String idioma							= null;

	 

	 /**

     *  Constructor vacío

     */

    public Q02bMailUtils() {

        super();

    }

    

    public String getSubject(){

    	return this.subject;

    }

    public void setSubject(String subject){

    	this.subject=subject;

    }

    

    public String getBody(){

    	return this.body;

    }

    public void setBody(String body){

    	this.body=body;

    }

    

    public String getRemitente(){

    	return this.remitente;

    }

    public void setRemitente(String remitente){

    	this.remitente=remitente;

    }

    

    public ArrayList getListaDestinatarios(){

    	return this.listaDestinatarios;

    }

    public void setListaDestinatarios(ArrayList listaDestinatarios){

    	this.listaDestinatarios=listaDestinatarios;

    }

    

    public Q02bAttachment[] getAttachment(){

    	return this.attachment;

    }

    public void setAttachment(Q02bAttachment[] attachment){

    	this.attachment = attachment;

    }

    

    public String getIdioma(){

    	return this.idioma;

    }

    public void setIdioma(String idioma){

    	this.idioma = idioma;

    }

    



/**

     * Método que envia el email a los destinatarios

     */

   public void enviarMail () throws Exception{ //recupera de las propiedades internas

   		//Variables que no se van a modificar

	    final String    TRACE_METODO 		= ":enviarMail:";

		//final String 	RECURSOS_COMUN		= "q02brecursosComun";

		//final String    MENSAJE				= "comun.mail.mansajeLOPD";

    	final String 	HOST_MAIL 			= Q70ListenerUtils.getApplicationProperty("HOST_MAIL");

		try{

			if (tr.isTraceActive()) {

	            tr.trace(COMPONENTE, Q70TraceLevel.INFO, TRACE_METODO +" inicio");

	        }

	    	//Variable donde se guarda el mensaje LOPD

			/*

			String mensajeLOPD	= "";	

			//Si se ha dado valor a la variable idioma, se recupera el mensaje LOPD

			if(!S99bFormatData.esVacio(this.idioma)){

				mensajeLOPD = Q70GestorMensajesi18n.getSingleton().getMessage(RECURSOS_COMUN,MENSAJE,this.idioma);

				//Se le añade al body el mensaje

				body += "\n-----------------------------------------------------------\n"+

						mensajeLOPD+"\n-----------------------------------------------------------\n";

			}*/

			

			//Se crea la estructura de envío de correos

		    Q70MailEnvelope mailEnvelope = new Q70MailEnvelope();

	    	mailEnvelope.setHost(HOST_MAIL); 	

	    	//Se crea el mensaje concreto a enviar

	    	Q70MailMessage mailMessage = new Q70MailMessage();

	    	//Se indican los atributos de asunto, cuerpo y remitente

	    	mailMessage.setAsunto(subject);

	    	mailMessage.setTextoPlano(body);

	    	mailMessage.setRemitente(new Q70MailUser(remitente));

	    	//Se indican los destinatarios del correo

	    	for(int i=0;i<listaDestinatarios.size();i++){

	    		String destinatario = (String)listaDestinatarios.get(i);

	    		if(destinatario.indexOf("<")!=-1){

	    			String nombre= "\""+((String)listaDestinatarios.get(i)).split("<")[0]+"\"";

		    		String direccionDestinatario= ((String)listaDestinatarios.get(i)).split("<")[1];

		    		direccionDestinatario = direccionDestinatario.replaceAll(">","");

		    		mailMessage.addDestinatarios(new Q70MailUser(nombre,direccionDestinatario));

	    		}else{

	    			mailMessage.addDestinatarios(new Q70MailUser(destinatario));

	    		}

	    	}	

	    	

	    	//Se comprueba si se quieren enviar ficheros

	    	if(attachment!=null && attachment.length > 0){

	    		//Se recorren los ficheros

	    		for(int i=0;i<attachment.length;i++){

	    			//Se obtiene el fichero en concreto

	    			Q02bAttachment attach = attachment[i];

	    			//Se crea el fichero según el Framework

	    			Q70MailFile fichero = new Q70MailFile(attach.getFileName(),attach.getInputStream(),attach.getFileContentType());

		    		//Se añade al mensaje

	    			mailMessage.addFicheroAdjunto(fichero);

	    		}

	    	}

	    	

	    	//Se añade a la estructura de envío del mensaje, el mensaje concreto

	    	mailEnvelope.setMessage(mailMessage);

	    	//Se envía el correo

	    	Q70Factoria.getGestorMail().dispatch(mailEnvelope);	  

	    }catch(Exception ex){

			java.io.StringWriter sw = new java.io.StringWriter();

	        java.io.PrintWriter out = new java.io.PrintWriter(sw);

	        ex.printStackTrace(out);

	        if (tr.isTraceActive()) {

	           tr.trace(COMPONENTE, Q70TraceLevel.ERROR, TRACE_METODO +

	            		sw.getBuffer().toString());

	        }

	        throw ex;

    	}finally{

    		if (tr.isTraceActive()) {

	            tr.trace(COMPONENTE, Q70TraceLevel.INFO, TRACE_METODO + " fin");

	        }

    	}

   }

    /**

     * Método que envia el email a los destinatarios

     */

    	/*

   public void enviarMail () throws Exception{ //recupera de las propiedades internas



	  

		    Q70MailEnvelope mailEnvelope = new Q70MailEnvelope();

	    	final String HOST_MAIL = Q70ListenerUtils.getApplicationProperty("HOST_MAIL");

	    	mailEnvelope.setHost(HOST_MAIL); 

	    	Q70MailMessage mailMessage = new Q70MailMessage();

	    	mailMessage.setAsunto(subject);

	    	mailMessage.setTextoPlano(body);

	    	if(!Q02bFormatData.esVacio(this.nombreArchivoAdjunto) && this.archivoAdjunto!=null && !Q02bFormatData.esVacio(this.tipoArchivoAdjunto));{

	    		Q70MailFile fichero = new Q70MailFile(this.nombreArchivoAdjunto,this.archivoAdjunto,this.tipoArchivoAdjunto);

	    		mailMessage.addFicheroAdjunto(fichero);

	    	} 

	    	mailMessage.setRemitente(new Q70MailUser(remitente));

	    	for(int i=0;i<listaDestinatarios.size();i++)

	    	{

	    		mailMessage.addDestinatarios(new Q70MailUser((String)listaDestinatarios.get(i)));

	    	}	

	    	mailEnvelope.setMessage(mailMessage);

	        		

	    	Q70Factoria.getGestorMail().dispatch(mailEnvelope);

	  

    }*/

   

   /**

    * Método que recibe un e-mail en función del servidor de correo, el usuario y password

    * y devuelve un array de tipo Q02bMessage con los datos recibidos del mismo

    * 

    * @param popServer

    * @param popUser

    * @param popPassword

    * 

    * @return Q02bMessage[]

    * 

    * @throws Exception

    * 

    */

    public static Q02bMessage[] recibirMail(String popServer, String popUser, String popPassword) throws Exception {

    	//Variables que no se modifican

    	final String BORRADO = "Q02B_CIRCUITOS_BORRADO_BUZONES_CORREO";

    	//Array que contiene la información a devolver

    	Q02bMessage[] Q02bMsg = null;

    	//Se declaran las variables a utilizar

    	Store 	store 	= null;

    	Folder 	folder	= null;

    	boolean borrado = true;

    	try{

    		//Se obtiene los componentes de la sesión

    		Properties 	props    = System.getProperties();

    		Session 	session  = Session.getDefaultInstance(props,null);

    		//Se indica que se va a abrir una conexión POP3, y se conecta

    		store				 = session.getStore("pop3");

    		store.connect(popServer,popUser,popPassword);

    		//Se obtiene lo que haya

    		folder = store.getDefaultFolder();

    		if(folder == null){

    			throw new Exception("No default folder");

    		}

    		folder = folder.getFolder("INBOX");

    		if(folder == null){

    			throw new Exception("No POP3 INBOX");

    		}

    		//Se comprueba si se ha habilitado la marca de activo

    		if(Q02bConstantes.MARCA_ACTIVO.equals(Q02bConstantes.getString(BORRADO))){

    			//Se abre el buzón para leer y modificarlo (eliminarlo posteriormente)

    			folder.open(Folder.READ_WRITE);

    		}else{

    			//Se abre el buzón para leer

    			folder.open(Folder.READ_ONLY);

    			//Se modifica el estado de la variable para que no elimine los mensajes

    			//de correo del buzón

    			borrado = false;

    		}

    		//Se obtienen los mensajes

    		Message[] msgs = folder.getMessages();

    		//Se crea un array con un tipo de objeto de la aplicación que almacenará

    		//la información que nos interesa

    		Q02bMsg = new Q02bMessage[msgs.length];

    		//Se recorren los mensajes obtenidos

    		for(int i=0;i<msgs.length;i++){

    			printMessage(msgs[i],Q02bMsg[i]=new Q02bMessage());

    			//Se elimina el mensaje del buzón

    			if(borrado){

    				msgs[i].setFlag(Flags.Flag.DELETED, true);

    			}

    		}

    	}catch(Exception ex){

			  java.io.StringWriter sw = new java.io.StringWriter();

              java.io.PrintWriter out = new java.io.PrintWriter(sw);

              ex.printStackTrace(out);

    	}finally{

    		try{

    			//Cierra la conexión;En función de la variable borrará o no los mensajes de correo

    			if(folder!=null){folder.close(borrado);}

    			if(store!=null){store.close();}

    		}catch(Exception ex){

    			java.io.StringWriter sw = new java.io.StringWriter();

                java.io.PrintWriter out = new java.io.PrintWriter(sw);

                ex.printStackTrace(out);

    		}

    	}

		//Se devuelve el array con los resultados

		return Q02bMsg;

    }

    

    /**

     * Método que recibe un objeto de tipo Message y lo analiza

     * 

     * @param Message  		message

     * @param Q02bMessage 	Q02bMessage

     * 

     */

    public  static  void  printMessage(Message  message, Q02bMessage Q02bMessage){ 

    	//Variable que no se van a modificar

    	final String HEADER_MESSAGE_ID = "Message-ID";

        try{  

        	//Se obtiene quién ha enviado el mensaje

            String  from  =  ((InternetAddress)message.getFrom()[0]).getPersonal();  

            if(from  ==  null){  

                    from  =  ((InternetAddress)message.getFrom()[0]).getAddress();  

            }  

            //Se obtiene a quien va dirigido

            String  to  =  ((InternetAddress)message.getAllRecipients()[0]).getPersonal();  

            if(to  ==  null){  

                    to  =  ((InternetAddress)message.getAllRecipients()[0]).getAddress();  

            }             

            //Se obtiene el asunto del mensaje

            String  subject  =  message.getSubject();  

            //Se obtiene la fecha en la cual se envió el mensaje

            Date 	date	 =  message.getSentDate(); 

                       

            //Se obtiene el contenido del mensaje

            Object  content  	 =  message.getContent();  

            //Se comprueba si el mensaje es multipart

            if (content instanceof Multipart) {

            	//Parte múltiple

            	procMultipart ((Multipart)content,Q02bMessage);

            }else{

            	//Parte Simple

            	procPart (message,Q02bMessage,new Vector());

            }

       

            //Se da valor a nuestra variable

            Q02bMessage.setTo(to);

            Q02bMessage.setFrom(from);

            Q02bMessage.setSubject(subject);

            Q02bMessage.setSentDate(date);

            Q02bMessage.setMessageId(getHeader(HEADER_MESSAGE_ID,message));

             

        }catch(Exception  ex){  

        	java.io.StringWriter sw = new java.io.StringWriter();

            java.io.PrintWriter out = new java.io.PrintWriter(sw);

            ex.printStackTrace(out);

        }  

    }

    

    /**

     * Método que lee mensaje MultiPart y lo procesa

     * 

     * @param Multipart 	mp

     * @param Q02bMessage 	Q02bMessage

     * 

     */

    public static void procMultipart(Multipart multipart,Q02bMessage Q02bMessage) throws MessagingException{

    	//Vector donde se almacenarán los distintos fichero

    	Vector v = new Vector();

    	//Se recorren las distintas partes del mensaje multipart

    	for (int i=0; i<multipart.getCount(); i++) {

    		//Se obtiene una de las partes

    		Part p= multipart.getBodyPart(i);

    		//Se procesa dicha parte

    		procPart(p,Q02bMessage,v);

    	}

    	//Se indica la parte multipart

    	Q02bMessage.setMultipart(multipart);

    	//Se crea un objeto que almacenará los ficheros

    	Q02bAttachment[] attachment = new Q02bAttachment[v.size()];

    	//Se recorren los attachments

    	for(int i=0;i<v.size();i++){

    		attachment[i] = (Q02bAttachment)v.elementAt(i);

    	}

    	//Se indica el array

    	Q02bMessage.setAttachment(attachment);

    }

    

    /**

     * Método que procesa la parte de un mensaje

     * 

     * @param Part 			p

     * @param Q02bMessage 	Q02bMessage

     * @param Vector		v

     * 

     */

    public static void procPart(Part part,Q02bMessage Q02bMessage,Vector v) {

    	try {

    		//Se recupera el contenido del mensaje

    		String contentType= part.getContentType();

    		//Se comprueba que el contentType tenga valor

    		if(contentType!=null){

	    		//Se comprueba si tiene otra parte que sea mçultiple

	    		if(contentType.toLowerCase().startsWith("multipart/")){

	    			//Se invocaría un método de forma recursiva

	    		}else{

	    			//Si el contenido es de tipo texto y no es un fichero, se obtiene el texto

	    			if (contentType.toLowerCase().startsWith("text/") 

	    					&& !"attachment".equals(part.getDisposition())){

	    				//Se declara en la variable del mensaje el texto

	    				Q02bMessage.setTxtMsg(readMsg(part));

	    			}else{//Si es un attachment se procesa

	    				//Se instancia el objeto

	    				Q02bAttachment attachment = new Q02bAttachment();

	    				//Se indica el nombre del fichero

		            	attachment.setFileName(part.getFileName());	

		            	//Se invoca una clase que clonará el inputstream del fichero

		            	Q02bCopyInputStream copy = new Q02bCopyInputStream(part.getInputStream());

		            	//Se lee el fichero para obtener la longitud del mismo

		            	attachment.setFileSize(Integer.toString(copy.read()));

		            	//Se guarda una copia

		            	attachment.setInputStream(copy.getCopy());

		            	//Se añade al vector

		            	v.add(attachment);

	    			}

	    		}

    		}

    	} catch (Exception ex) {

    		java.io.StringWriter sw = new java.io.StringWriter();

            java.io.PrintWriter out = new java.io.PrintWriter(sw);

            ex.printStackTrace(out);

    	}

    }

    

    /**

     * Método que recibe un objeto de tipo Part y devuelve el texto

     * 

     * @param  Part messagePart

     * 

     * @return String - Se devuelve el texto del mensaje de correo

     */

    private static String readMsg (Part messagePart){ 

    	 //Variable donde se almacena el texto del mensaje

    	 StringBuffer txtMsg = new StringBuffer(); 

    	 try{

             InputStream  	is  		=  messagePart.getInputStream();  

             BufferedReader  reader  	=  new  BufferedReader(new  InputStreamReader(is));  

             String  		thisLine  	=  reader.readLine();  

             while(thisLine  !=  null){ 

            	txtMsg.append(thisLine); 

                thisLine  =  reader.readLine();  

             }    

    	 }catch(MessagingException ex){  

         	 java.io.StringWriter sw = new java.io.StringWriter();

             java.io.PrintWriter out = new java.io.PrintWriter(sw);

             ex.printStackTrace(out);

    	 }catch(IOException ex){  

        	 java.io.StringWriter sw = new java.io.StringWriter();

        	 java.io.PrintWriter out = new java.io.PrintWriter(sw);

        	 ex.printStackTrace(out);

    	 } 

    	 //Se devuelve el texto del mensaje

         return txtMsg.toString();

    }

    

    /**

     * Método que devuelve el contenido de un header que se le pasa como parámetro

     * en un mensaje

     * 

     * @param  String  header

     * @param  Message message

     * 

     * @return String

     */

    private static String getHeader(String header, Message message){

        String[] list = null;



        try{

            list = message.getHeader(header);

        }

        catch (MessagingException e){}



        if ((list == null) || (list.length < 1)){

            return null;

        }



        return list[0];

    }

}

