/*
 * Fichero:     ComercioP2P.java
 * Fecha:       26/11/2006
 * Autor:       Alvaro Sarmiento Losada
 * Asignatura:  Proyecto Fin de Carrera
 * Descripción: Contiene a un cliente de comercio electrónico, el cual 
 * 	mandará mensajes de compra a unservidor de comercio para poder obtener
 *  un cierto producto.
 *
 * Este fichero pertenece al proyecto fin de carrera del autor,
 * consistente en el estudio de JXTA y su aplicación al comercio 
 * electrónico b2b.
 */
package com.pfc.comercio.p2p;

import com.pfc.lib.p2p.*;
import com.pfc.lib.utiles.FactoriaAleatoria;
import com.pfc.lib.utiles.FechaISO8601;
import com.pfc.lib.xml.DocumentoXML;
import com.pfc.lib.xml.ExcepcionMensajeXML;
import com.pfc.lib.xml.MensajeXML;
import com.pfc.lib.xml.cxml.*;
import com.pfc.manejadores.*;
import com.pfc.ventanas.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import java.util.ListIterator;
import net.jxta.protocol.PeerAdvertisement;
import org.jdom.*;
import org.jdom.Element;
import org.jdom.Namespace;


/**
 * Clase cliente de nuestro servicio de comercio electrónico. Se encarga  de la creación de mensajes de compra y de comprobar si ésta pudo o no efectuarse.
 * @author  Alvaro Sarmiento Losada
 */
public class ClienteCompra {
	
	/** 
     * El dominio de los credenciales que se usará en la aplicación de
     * ComercioP2P.
     */
    public static final String DOMINIO_COMERCIOP2P = "Comercio-Id";
    
    /**
     * El agente de usuario que representa este objeto, y que aparecerá
     * en el elemento "Sender" de las peticiones.
     */
    private final String AGENTE = "Agente ComercioP2P v1.0";
    
    /**
     * El directorio donde están almacenado el archivo que contiene las
     * claves.
     */

    
    public static final String CLAVES = "C:/Documents and Settings/Antonio/Mis documentos/cosas alvaro/proyecto_alvaro/claves.xml.txt";

    /**
     * El archivo que contiene las claves para ser enviadas en las peticiones
     * cXML en el elemento "SharedSecret".
     */

    
    private static final String OPERACION_COMPRA = "OrderResponse";
    
	
	ClienteComercioP2P cliente=null;
	
	
	/** Instanciación de un elemento de esta clase*/
	public ClienteCompra(GrupoDePeers grupo){
	
		cliente = new ClienteComercioP2P(grupo);
		System.out.println("Creamos el cliente del comercio");
	}  
	
	
	/** Realiza una busqued por la red JXTA de un comerciante que tenga un determinado nombre
	 * 
	 * @param grupo El grupo de peers al que pertenece el cliente 
	 * @param proveedor Arreglo en donde se encuentran datos del proveedor
	 * @param comprador Arreglo con datos del comprador
	 */
	public void buscarComerciante(GrupoDePeers grupo,String []proveedor,String []comprador){
		grupo.descubrirPeers(null, null);
		/*Ponemos osito porque es el nombre que le hemos dado a nuestro peer que hace de servidor*/
		Enumeration enumPeers = grupo.descubrirPeersDelCache("Name",proveedor[2]); 
	
		if(enumPeers!=null){
			System.out.println("Se ha encontrado algo");
		}
	
		boolean salir=false;     	        
		while ( (enumPeers.hasMoreElements() == true) && (enumPeers != null) && salir!=true) {
			System.out.println("Probemos con este anuncio"); 
			PeerAdvertisement anuncio=(PeerAdvertisement)enumPeers.nextElement();
			System.out.println(anuncio);
			cliente.setDestinatario(anuncio);
			/*Debemos escoger el tipo de operacion a realizar:compra o perfil*/
			salir=realizarGestion(proveedor,comprador);
		}
	}
	
	
	/** Método que pide la generación de un mensaje de compra, lo lanza y está a la espera para comprobar su validez
	 * 
	 * @param proveedor Datos del proveedor
	 * @param comprador Datos del comprador
	 * @return True si todo fue correcto. Eoc false
	 */
	public boolean realizarGestion(String[] proveedor,String []comprador){
		boolean solucion=false;
		gestorVentanas gestor=new gestorVentanas();
		PeticionCXML peticion=generarPeticionCompra(proveedor,comprador);
		System.out.println(peticion);
		MensajeXML message=new MensajeXML();
		Document doc=peticion.getDocumento();
		DocumentoXML docu=new DocumentoXML(doc);
		message.setDocumentoXML(docu);
		try{
			message.enviarMensajeXML();
			System.out.println("Se ha enviado una peticion de compra");
		}catch(Exception e){
			e.printStackTrace(System.out);
		}
		MensajeXML mensajeRespuesta = new MensajeXML();
		 try {		 
             //Se pone a la escucha para recibir mensajes XML
             mensajeRespuesta.recibirMensajeXML();
             //Si llega aquí, es que se ha recibido un mensaje nuevo
             System.out.println("Se ha recibido exitosamente un mensaje");
         } catch (ExcepcionMensajeXML emx) {
             //Se ha recibido algo, pero con algún tipo de error
             System.out.println("Se ha generado una excepcion al recibir un mensaje");            
         }
         
         DocumentoXML documentoPeticion = mensajeRespuesta.getDocumentoXML();
         
         if( documentoPeticion != null ) {
             
             /* Se comprueba que la petición recibida es válida */
             if ( documentoPeticion.esValido() == true ) {
            	 System.out.println("El documento era válido");          
            	 RespuestaCXML respuesta= new RespuestaCXML();
            	 respuesta.setDocumento( documentoPeticion.getDocumento() ); 	 
            	 String devolucion=respuesta.getTipoRespuestaEnString();
            	 if(devolucion.equals(OPERACION_COMPRA)){
            		 ManejadoresMensajesSoap manejador=new ManejadoresMensajesSoap();
            		 String codigo=respuesta.getCodigoStatus();
            		 manejador.operacionCompra(codigo);
            		 
            	 }
             }else{
            	 System.out.println("No era valido el Documento");
            	 gestor.error();
             }
             
         }else
        	 System.out.println("No se ha recibido nada");
         
         
         /*Se comprueba que lo recibido es lo correcto*/
		
		return solucion;
	}
	
	
	/** Me´todo para la generación del mensaje de compra
	 * 
	 * @param proveedor Datos del proveedor
	 * @param comprador Datos del comprador
	 * @return La peticion de compra generada
	 */
	public PeticionCXML generarPeticionCompra(String []proveedor,String[]comprador){
		
		//PeticionCXML peticion=new PeticionCXML();
		
        String dominio ="Usuarios Catalogo 1.0";
        
        
        //Se genera el esqueleto básico de la petición cXML
        PeticionCXML pet = generarPeticionCXML(comprador, 
                                                    dominio, 
                                                    proveedor);
        /* 
         * Se genera el cuerpo de la petición de compra
         */
        Element tipoPeticion = new Element(PeticionCXML.PETICION_COMPRA);

        /* Se crea la cabecera de la petición */
        Element cabecera = new Element("OrderRequestHeader");
        cabecera.setAttribute("orderID",
                              FactoriaAleatoria.cadenaNumericaAleatoria() );
        cabecera.setAttribute("orderDate",FechaISO8601.fechaISO());
        cabecera.setAttribute("type","new");
        
        //Se crea el elemento cXML "Total"
        Element total = new Element("Total");
        Element money = new Element("Money");
        money.setAttribute("currency","EUR");
        Integer j = Integer.valueOf(proveedor[3]);
        int prec =  j.intValue();
        money.setText(String.valueOf(prec));
        total.addContent(money);
        
        //Se crea el elemento cXML "ShipTo"
        Element enviar = new Element("ShipTo");
        Element dirEnviar = new Element("Direccion");
        Element nombreEnviar = new Element("Nombre");        
        Element dirpostalEnviar = new Element("DireccionPostal");
       // Element entregarEnviar = new Element("DeliverTo");
        Element calleEnviar = new Element("Calle");
        Element ciudadEnviar = new Element("Localidad");
        Element estadoEnviar = new Element("Provincia");
        Element cpEnviar = new Element("CodigoPostal");
        Element paisEnviar = new Element("Pais");
        paisEnviar.setAttribute("isoCountryCode", "ES");
        nombreEnviar.setAttribute("lang","es", Namespace.XML_NAMESPACE);
        nombreEnviar.setText(comprador[0]);
       // entregarEnviar.setText(origen.getNombreEnviar());
        calleEnviar.setText(comprador[1]);
        ciudadEnviar.setText(comprador[2]);
        estadoEnviar.setText(comprador[3]);
        cpEnviar.setText(comprador[4]);
        paisEnviar.setText(comprador[5]);
        //dirpostalEnviar.addContent(entregarEnviar);
        dirpostalEnviar.addContent(calleEnviar);
        dirpostalEnviar.addContent(ciudadEnviar);
        dirpostalEnviar.addContent(estadoEnviar);
        dirpostalEnviar.addContent(cpEnviar);
        dirpostalEnviar.addContent(paisEnviar);
        dirEnviar.addContent(nombreEnviar);
        dirEnviar.addContent(dirpostalEnviar);
        enviar.addContent(dirEnviar);
        
        //Se crea el elemento cXML "BillTo"
        Element facturar = new Element("BillTo");
        Element dirFacturar = new Element("Direccion");
        Element nombreFacturar = new Element("Nombre");
        Element dirpostalFacturar = new Element("DireccionPostal");
        Element calleFacturar = new Element("Calle");
        Element ciudadFacturar = new Element("Localidad");
        Element estadoFacturar = new Element("Provincia");
        Element cpFacturar = new Element("CodigoPostal");
        Element paisFacturar = new Element("Pais");
        paisFacturar.setAttribute("isoCountryCode", "ES");
        nombreFacturar.setAttribute("lang","es", Namespace.XML_NAMESPACE);
        nombreFacturar.setText(proveedor[2]);
        calleFacturar.setText(proveedor[5]);
        ciudadFacturar.setText(proveedor[7]);
        estadoFacturar.setText(proveedor[9]);
        cpFacturar.setText(proveedor[11]);
        paisFacturar.setText(proveedor[13]);
        dirpostalFacturar.addContent(calleFacturar);
        dirpostalFacturar.addContent(ciudadFacturar);
        dirpostalFacturar.addContent(estadoFacturar);
        dirpostalFacturar.addContent(cpFacturar);
        dirpostalFacturar.addContent(paisFacturar);
        dirFacturar.addContent(nombreFacturar);
        dirFacturar.addContent(dirpostalFacturar);
        facturar.addContent(dirFacturar);                
        
        /*Para esto podria hacer una ventana*/
        //Se crea el elemento cXML "Payment"
        Element pago = new Element("Payment");
        Element tarjeta = new Element("tarjeta");
        tarjeta.setAttribute("number", proveedor[3]);
        tarjeta.setAttribute("expiration", proveedor[3]);
        pago.addContent(tarjeta);
        
        cabecera.addContent(total);
        cabecera.addContent(enviar);
        cabecera.addContent(facturar);
        cabecera.addContent(pago);
        // La cabecera de la petición está terminada
        
        /* Se crea el elemento que define el producto "ItemOut" */
        Element itemOut = new Element("ItemOut");
        itemOut.setAttribute("quantity", "1");
        
        //Se crea el elemento cXML "Tax"
        Element tax = new Element("Tax");
        Element dineroTax = new Element("Money");
        dineroTax.setAttribute("currency","EUR");
        dineroTax.setText("16");
        Element descrTax = new Element("Description");
        descrTax.setAttribute("lang","es", Namespace.XML_NAMESPACE);
        descrTax.setText("IVA");
        tax.addContent(dineroTax);
        tax.addContent(descrTax);
        
        //Se crea el elemento cXML "Shipping"
        Element envio = new Element("Shipping");
        Element dineroEnvio = new Element("Money");
        dineroEnvio.setAttribute("currency","EUR");
        dineroEnvio.setText("10");
        Element descrEnvio = new Element("Description");
        descrEnvio.setAttribute("lang","es", Namespace.XML_NAMESPACE);
        descrEnvio.setText("UPS");
        envio.addContent(dineroEnvio);
        envio.addContent(descrEnvio);
        
        Element id = new Element("id");
        id.setText(proveedor[0]);
        Element nombre = new Element("Nombre");
        nombre.setText(proveedor[2]);
        
        itemOut.addContent(id);
        itemOut.addContent(nombre);
        itemOut.addContent(envio);
        itemOut.addContent(tax);
        //El elemento "ItemOut" está terminado
        
        tipoPeticion.addContent(cabecera);
        tipoPeticion.addContent(itemOut);

        pet.setTipoPeticion(tipoPeticion);
       

        return pet;
		
	}
	
	/** Produce un mensaje de petición CXML general
	 * 
	 * @param comprador Datos del comprador
	 * @param dominioFrom Cadena que expresa el servicio en el que estamos
	 * @param proveedor Datos del proveedor
	 * @return
	 */
	protected PeticionCXML generarPeticionCXML(String[] comprador,String dominioFrom, String[] proveedor) {

		 PeticionCXML peticion = new PeticionCXML();
	        //Se establece el elemento "From"
	        peticion.setIdentidadFrom(comprador[0]);
	        peticion.setDominioCredencialFrom(dominioFrom);
	        //Se establece el elemento "To"
	        peticion.setIdentidadTo(proveedor[2]);
	        peticion.setDominioCredencialTo(DOMINIO_COMERCIOP2P);        
	        /*
	         * Se establece el elemento "Sender", usando la información del
	         * propio peer.
	         */
	        peticion.setIdentidadSender(comprador[0]);
	        peticion.setDominioCredencialSender(DOMINIO_COMERCIOP2P);        
	        peticion.setClaveSender(obtenerClave(comprador[0]));
	        peticion.setAgente(AGENTE);
	        
	        return peticion;
	}
	
	/** Obtiene la clave necesaria para la operación de compra
	 * 
	 * @param destino El nombre del peer proveedor
	 * @return La clave buscada
	 */
	public String obtenerClave(String destino) {
        //En principio, se devuelve una clave vacía
        String clave = "";
        //Se abre el fichero de claves
        File archivo = new File(CLAVES);
              
        try {
            //Se obtiene el documento XML almacenado en el archivo de claves
            DocumentoXML lista = new DocumentoXML(archivo);
            Element raiz = lista.getElementoRaiz();
            //Se obtiene la lista de elementos "Credential" del documento
            List listaCredenciales = raiz.getChildren("Credential");
            ListIterator iterador = listaCredenciales.listIterator();
            
            /*
             * Se itera sobre la lista hasta encontrar un elemento que 
             * coincida en nombre con el destino especificado, y se toma
             * la clave almacenada.
             */
            boolean seguir = true;
            while ( (seguir == true) && (iterador.hasNext() == true) ) {
                Element siguiente = (Element) iterador.next();
                String identidad = siguiente.getChildText("Identity");
                
                /*
                 * Se comprueba que este elemento corresponda al destino
                 * especificado.
                 */
                if ( identidad.equals(destino) == true ) {
                    /*
                     * Se ha encontrado la clave para el destino especificado,
                     * no se itera más.
                     */
                    seguir = false;
                    //Se obtiene la clave
                    clave = siguiente.getChildText("SharedSecret");
                } 
            }
        } catch (IOException ioe) {
            /*
             * Si ocurre algún error con el archivo de claves, se 
             * devuelve una cadena vacía, es decir, que no hay clave.
             */
            clave = "";
        }

        return clave;
    }
	
	
	/** Método que obtiene los datos del comprador
	 * 
	 * @param nombre_archivo El archivo en donde se encuentran los datos
	 * @return Arreglo que contiene la información deseada
	 */
	public String[] datosComprador(String nombre_archivo,String nombre){
		String[] sigo=new String[100];
		int i=0;
		try{
    		BufferedReader br = new BufferedReader(new FileReader(nombre_archivo));
    		String s;                  	    
    		 
    		while ((s = br.readLine())!= null) {
    			sigo[i]=s;
    			i++;
    		}
    	}catch(Exception e){
    		e.printStackTrace(System.out);
    	}
    	boolean seguir=true;
    	String []array=new String[6];
    	
    	for(i=0;sigo[i]!=null && seguir!=false;i++){
    		int j=0;
        	int contador=0;
        	int indice=0;
        	boolean exit=false;
    		String apoyo=new String();
    		for(j=0;exit!=true;j++){
				indice=sigo[i].indexOf(":",contador);			
				apoyo=sigo[i].substring(contador,indice);
				System.out.println(apoyo);
				indice++;
				contador=indice;

				if(apoyo.equals("final2"))
					exit=true;
				else
					array[j]=apoyo;
			}
    		
    	}
    	
    	array[0]=nombre;
    	
    	return array;
	}
}
