package com.pfc.catalogop2p.p2p;

import com.pfc.lib.soap.*;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;


import javax.xml.soap.*;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
//import org.apache.axis.utils.*;


import com.pfc.ventanas.*;
import com.pfc.manejadores.*;
import com.pfc.lib.utiles.*;


/** Clase que representa las funciones que debe realizar el cliente
 * 
 * @author Alvaro Sarmietno Losada
 *
 */
public class ClienteServicio {
	
	public final static String REGISTRAR = "registrar";
	public final static String BUSCAR = "buscar";
	public final static String ELIMINAR = "eliminar";
	public final static String PRODUCTOSREGISTRADOS = "registros";
	public final static String PRODUCTOSBUSCADOS = "buscados";
	
	public final static String PRIMERREGISTRO= "primerregistro.txt";
	public final static String PROVEE= "proveedor.txt";
	public final static String PROVEEDORES= "proveedores.txt";
	public final static String NUESTROSPRODUCTOS= "nuestrosproductos.txt";
	
	public final static String EXCEPCION= "Se produjo una excepcion en el servidor";
	public final static String ERROR= "Su peticion no era correcta";
	public final static String ERRORBUSQUEDA= "No se encuentra en la base de datos";
	public final static String ERRORELIMINACION= "No ha podido eliminarse";
	public final static String BIEN= "Su peticion se ha realizado correctamente";
	
	
	/** Constructor por defecto*/
	public ClienteServicio(){
		super();
	}

	/** Método principal del cliente del servicio Catalogo
	 * 
	 * @param peticion Indica que tipo de petición vamos a realizar
	 * @param ultimo Expresa cúal es nuestro nombre en la red JXTA  
	 
	 * 
	 */
	public void invocarServicio(String peticion,String ultimo){
		
		ManejadoresMensajesSoap manejador= new ManejadoresMensajesSoap();
		
		
		manejador.almacenarDatosPropios(ultimo);	
		
		/*Se entra en donde haya escogido el usuario*/
		if(peticion.equals(REGISTRAR)){
			registrar(ultimo);
		}else if(peticion.equals(BUSCAR)){
			buscar(ultimo);
		}else if(peticion.equals(ELIMINAR)){
			eliminar(ultimo);
		}else if(peticion.equals(PRODUCTOSREGISTRADOS)){
			mostrarRegistros();
		}else if(peticion.equals(PRODUCTOSBUSCADOS)){
			mostrarBusquedas();
		}else
			System.out.println("Error en la peticion");
		
		
	}
	
	/** Método que nos permite registrar nuestros productos en la base de datos
	 * 
	 * @param ultimo El nombre de nuestro par la última vez que nos conectamos
	 */
	public void registrar(String ultimo){
		gestorVentanas gestor=new gestorVentanas();
		Log log=new Log("log_aplicacion");
		ManejadoresMensajesSoap manejador= new ManejadoresMensajesSoap();
		
		File provee=new File(PRIMERREGISTRO);
		
		/* Si no es la primera vez que registramos algo*/
		if(provee.exists())
			System.out.println("Ya habia registrado algo antes");
		
		/* Si vamos a registrar por primera vez*/
		else{
			
			
			try{
				String  []datos=null;
				String total="Registramos por primera vez";
				
				File pro=new File(PRIMERREGISTRO);
				FileWriter escritor = new FileWriter(pro,true);                     		
   		 		escritor.write(total);
   		 		escritor.write("\r\n");
   		 		escritor.flush();

   		 		escritor.close();
			
   				BufferedReader br = new BufferedReader(new FileReader(PROVEE));
        		String s=br.readLine();                  	    
        		ManejadoresCadenas man_cadenas=new ManejadoresCadenas();
        		datos=man_cadenas.datosProveedor(s);
   					
				PeticionProveedor registro = new PeticionProveedor(datos);
				
				SOAPMessage mySoapMessage=registro.devolverMensaje();
	
				SOAPMessage resultado=manejador.envioRecepcionMensajeSoap(mySoapMessage);
				if(resultado==null){
					System.out.println("No ha podido registrarse en la tabla de proveedores");
					log.apuntar("No ha podido registrarse en la tabla de proveedores");
				}
			}catch(Exception e){
				log.apuntar(e.getMessage());
        		e.printStackTrace(System.out);
        	}
		}
	
		String tipo_registro=gestor.elegirtipoRegistro();
		
		/*Si queremos registrar productos sueltos*/
		if(tipo_registro=="registrar_productos"){
			boolean exit=false;
			while(exit!=true){
			
				String[]tabla=new String[100];
				tabla=gestor.elementosRegistro();
				int contador=Integer.parseInt(tabla[4]);
				int i=0;
				int k=0;
				int elementos=0;
				String []result=new String[100];
				for(i=0;tabla[i]!="atributos";i++){	
					elementos++;
					result[i]=tabla[i];
				}
				result[3]=ultimo;
				elementos++;
				
				if(contador>0){ /*Tenemos atributos*/
					/*Siempre debemos indicar el precio de nuestros elementos*/
					String []precio=gestor.obtenerPrecio();
					result[elementos++]="atributo";
					result[elementos++]=precio[0];
					result[elementos++]="valor";
					result[elementos++]=precio[1];
				
					for(k=0;k<(contador-1);k++){ /*Se quita uno porque ya hemos atendido al precio*/
					
						String[] tabla2=gestor.elementosAtributo();
						i=0;
						for(i=0;i<tabla2.length;i++,elementos++)
							result[elementos]=tabla2[i]; 
					}
				}
				
				
				/*Generamos la peticion*/
				PeticionRegistro registro = new PeticionRegistro(result);
				
				int indice=0;
		
				for(i=0;result[i]!="atributo";i++)
					indice++;
		
				/*Añadimos atributos*/
				SOAPMessage nuevo=null;
				for(i=indice;result[i]!=null;i++){
					String []aux=new String[2];
					aux[0]=result[i];
					aux[1]=result[i+1];
					i++;
					nuevo=registro.devolverMensaje();
					SOAPMessage nuevo2=manejador.anadirAtributos(nuevo,aux);
					registro.colocarMensaje(nuevo2);
				}
				nuevo=registro.devolverMensaje();	
				
				SOAPMessage resultado=manejador.envioRecepcionMensajeSoap(nuevo);
				
				/*Comprobamos el mensaje devuelto*/
				String []identificador=manejador.comprobarLista(resultado);
				
				if(identificador[0].equals(ERROR)){
					gestor.error();
				}else if(identificador[0].equals(EXCEPCION)){
					gestor.excepcion();
				}else{
					
				
					File archiv=new File(NUESTROSPRODUCTOS);
				
					String producto=new String();
					producto=identificador[0]+":";
					
					for(k=0;result[k]!=null;k++){
						producto=producto+result[k]+":";
					}
					producto=producto+"final2:";
					
					try{
						FileWriter escritor = new FileWriter(archiv,true);                     		
						escritor.write(producto);
						escritor.write("\r\n");
						escritor.flush();
         
						escritor.close();
						gestor.bien();
						log.apuntar("se ha registrado un producto");
					}catch(IOException e){
						e.printStackTrace(System.out);
					}
					
					String resp=gestor.otroProducto();
					if(resp!="si")
						exit=true;
				}
			}
			
	    /*Si queremos registrar productos almacenados en un catalogo*/
		}else{
			/*Llamamos a una funcion en donde se guarda la ruta en un String*/
			String []productos= new String[100];
			int j=0;
			try {
		        SAXBuilder builder=new SAXBuilder(false); 
		        //usar el parser Xerces y no queremos 
		        //que valide el documento
		        String ruta=gestor.eleccionCatalogoRegistro();
		        File archivo=new File(ruta);
		        Document doc=builder.build(archivo);
		        //construyo el arbol en memoria desde el fichero
		        // que se lo pasaré por parametro.
		        Element raiz=doc.getRootElement();
		        //cojo el elemento raiz
		        
		        List nuevoproductos=raiz.getChildren("nuevo_producto");
		        System.out.println("Formada por:"+nuevoproductos.size()+" equipos");
		        Iterator i = nuevoproductos.iterator();
		        while (i.hasNext()){
		        	productos[j++]="nuevo_producto";
		            Element e= (Element)i.next();
		            Element categoria =e.getChild("categoria");
		            productos[j++]=categoria.getText();
		            Element producto =e.getChild("producto"); 
		            productos[j++]=producto.getText();
		            Element catalogo =e.getChild("catalogos"); 
		            productos[j++]=catalogo.getText();
		            productos[j++]=ultimo;
		            Element atributos =e.getChild("atributos"); 
		            List atri=atributos.getChildren("atributo");
		            Iterator it=atri.iterator();
		            List val=atributos.getChildren("valor");
		            Iterator value=val.iterator();
		            String[] atributo=new String[atri.size()];
		            int cont=0;
		            while(it.hasNext()){
		            	Element ayuda=(Element)it.next();
		            	atributo[cont]=ayuda.getText();
		            	cont++;
		            }
		            String[]valor=new String[val.size()];
		            cont=0;
		            while(value.hasNext()){
		            	Element ayuda=(Element)value.next();
		            	valor[cont]=ayuda.getText();
		            	cont++;
		            }
		            for(cont=0;cont<valor.length;cont++){
		            	productos[j++]="atributo";
		            	productos[j++]=atributo[cont];
		                productos[j++]="valor";
		                productos[j++]=valor[cont];
		            }
		          
		        }
		        int cont=0;
		        for(j=0;productos[j]!=null;j++)
					cont++;
				String [] solucion=new String[cont];
					
				for(j=0;j<cont;j++){
					solucion[j]=productos[j];
					System.out.println(solucion[j]);
					
				}
						
		        cont=0;
		        int k=0;
		        
		        int ind=1;
		        while(k<nuevoproductos.size()){
		        	String []regist=new String[100];
		        	int m=0;
		        	for(j=ind;j<solucion.length && solucion[j]!="nuevo_producto" ;j++){			        	
		        		regist[m]=solucion[j];
		        		m++;
		        	}
		        	ind=ind+m;
		        	
		        	
					
		        	PeticionRegistro registro = new PeticionRegistro(regist);
					
					int indice=0;
			
					for(m=0;regist[m]!="atributo";m++)
						indice++;
			
					SOAPMessage nuevo=null;
					for(m=indice;regist[m]!=null;m++){
						String []aux=new String[2];
						aux[0]=regist[m];
						aux[1]=regist[m+1];
						m++;
						nuevo=registro.devolverMensaje();
						SOAPMessage nuevo2=manejador.anadirAtributos(nuevo,aux);
						registro.colocarMensaje(nuevo2);
					}
					
					nuevo=registro.devolverMensaje();
					
					SOAPMessage resultado=manejador.envioRecepcionMensajeSoap(nuevo);
					
					/*Comprobamos el mensaje devuelto*/
					String []identificador=manejador.comprobarLista(resultado);
					
					if(identificador[0].equals(ERROR)){
						gestor.error();
					}else if(identificador[0].equals(EXCEPCION)){
						gestor.excepcion();
					}else{
						/* Si no hay error almacenamos informacion de los productos registrados en un fichero*/
						File archiv=new File(NUESTROSPRODUCTOS);
						String producto=new String();
						producto=identificador[0]+":";
						for(j=0;regist[j]!=null;j++){
							producto=producto+regist[j]+":";
						}
						producto=producto+"final2:";
						try{
							FileWriter escritor = new FileWriter(archiv,true);                     		
							escritor.write(producto);
							escritor.write("\r\n");
							escritor.flush();
							escritor.close();
							gestor.bien();
						}catch(IOException e){
							e.printStackTrace(System.out);
							log.apuntar(e.getMessage());
						}
					}
				
		        	ind++;
		        	k++;
		        }
		        log.apuntar("se han registrado todos los productos de un catálogo");
		        
		     }catch (Exception e){
		        e.printStackTrace();
		        log.apuntar(e.getMessage());
		     }	
		}
	}
	
	
	/** Método para buscar productos en nuestra base de datos
	 * 
	 * @param ultimo El nombre de nuestro par 
	 */
	public void buscar(String ultimo){
		gestorVentanas gestor=new gestorVentanas();
		ManejadoresMensajesSoap manejador= new ManejadoresMensajesSoap();
		Log log=new Log("log_aplicacion");
		
		
		/*Veamos el tipo de búsqueda*/
		String tipo_busqueda=gestor.tipoBusqueda();
		
		/*En caso de querer buscar productos concretos*/
		if(tipo_busqueda=="busca"){
			
			String[] elementos_busqueda=gestor.elementosBusqueda();
			
			int contador=Integer.parseInt(elementos_busqueda[3]);
			int i=0;
			int k=0;
			int elementos=0;
			String []result=new String[100];
			for(i=0;elementos_busqueda[i]!="atributos";i++){	
				elementos++;
				result[i]=elementos_busqueda[i];
			}

			for(k=0;k<contador;k++){
				
				String[] atributos=gestor.elementosAtributo();
				i=0;
				for(i=0;i<atributos.length;i++,elementos++){
					if(atributos[i].equals("precio")){
						String comparacion=gestor.precioMayorMenor();
						result[elementos++]=atributos[i];
						result[elementos++]="comparacion";
						result[elementos]=comparacion;
					}else
						result[elementos]=atributos[i];
					
				}
					
			}
			
			PeticionBusqueda busqueda = new PeticionBusqueda(elementos_busqueda);
			
			int cont=0;
			int indice=0;
			
			for(i=0;result[i]!="atributo";i++)
				indice++;
			for(i=indice;i<result.length;i++)
				cont++;
			SOAPMessage nuevo=null;
			for(i=indice;result[i]!=null;i++){
				String []aux=new String[2];
				aux[0]=result[i];
				aux[1]=result[i+1];
				i++;
				nuevo=busqueda.devolverMensaje();
				SOAPMessage nuevo2=manejador.anadirAtributos(nuevo,aux);
				busqueda.colocarMensaje(nuevo2);
			}
			nuevo=busqueda.devolverMensaje();			
			
			SOAPMessage resultado=manejador.envioRecepcionMensajeSoap(nuevo);
			
			String []devolucion=manejador.comprobarLista(resultado);
			if(devolucion[0].equals(ERROR)){ /*Buscaba un elemento que no existia*/
				gestor.error();
				
			}else if(devolucion[0].equals(EXCEPCION)){
				gestor.excepcion();
			}else if(devolucion[0].equals(ERRORBUSQUEDA)){
				gestor.errorBusqueda();
			}else{
				for(i=0;i<devolucion.length;i++)
					System.out.println(devolucion[i]);
				gestor.bien();
				log.apuntar("se ha realizado una búsqueda en la base de datos");
			}
			
		}
		/* En caso de querer listar los productos de la base de datos*/
		else{
			
			String tipo_lista=gestor.tipoLista();
			
			/* Si queremos listar las categorías*/
			if(tipo_lista=="categoria"){
				varCategoria cat=new varCategoria();
				SOAPMessage category=cat.devolverMensaje();
				String cat_elegida=manejador.visualizar(category);
				if(cat_elegida.equals(ERROR)){
					System.out.println(ERROR);
					gestor.error();
				}else if(cat_elegida.equals(EXCEPCION)){
					gestor.excepcion();
				}else if(cat_elegida.equals(ERRORBUSQUEDA)){
					gestor.errorBusqueda();
				}else{
					productosCategoria prod=new productosCategoria(cat_elegida);
					SOAPMessage product=prod.devolverMensaje(); 
					/*Listamos los productos de esa categoría*/
					String prod_elegido=manejador.visualizar(product);
					atributosProducto atri=new atributosProducto(cat_elegida,prod_elegido);
					SOAPMessage atribut=atri.devolverMensaje();
					/*Listamos los atributos para la categoría y producto elegidos*/
					manejador.visualizarAtributos(atribut);
				}
				
			}
			/*Si pretendemos listar los productos que hay en la base de datos*/
			else if(tipo_lista=="producto"){
				varProducto prod=new varProducto();
				SOAPMessage product=prod.devolverMensaje();
				String prod_elegido=manejador.visualizar(product);
				if(prod_elegido.equals(ERROR)){
					System.out.println(ERROR);
					gestor.error();
				}else if(prod_elegido.equals(EXCEPCION)){
					gestor.excepcion();
				}else if(prod_elegido.equals(ERRORBUSQUEDA)){
					gestor.errorBusqueda();
				}else{
					ProductoAtributo atri=new ProductoAtributo(prod_elegido);
					SOAPMessage atribut=atri.devolverMensaje();
					/*Visualizamos los atributos del producto elegido*/
					manejador.visualizarAtributos(atribut);
				}
				
			}
			/*Visualizar todos los atributos de la base de datos*/
			else{
				varAtributos atri=new varAtributos();
				SOAPMessage atribut=atri.devolverMensaje();
				manejador.visualizarAtributos(atribut);
				
			}
			log.apuntar("Se han listado productos que hay en la base de datos");
		}
	}
	
	
	
	/** Permite eliminar productos de la based de datos
	 * 
	 * @param ultimo El nombre de nuestro par  
	 * 	a la red JXTA
	 */
	public void eliminar(String ultimo){
		gestorVentanas gestor=new gestorVentanas();		
		ManejadoresMensajesSoap manejador= new ManejadoresMensajesSoap();
		Log log=new Log("log_aplicacion");
		
		String numero_elementos=gestor.elementosParaEliminar();
		
		int contador=Integer.parseInt(numero_elementos);
		String []id_producto=new String[contador];
		
		for(int i=0;i<contador;i++){	
			id_producto[i]=gestor.eliminarElementos();
		}
		
		String par=ultimo;
		/*Suponemos que cuando se registra un producto en el mensaje SOAP de vuelta nos venga un número con el que identificar nuestro producto en la base de datos*/
	
		PeticionEliminar elimina = new PeticionEliminar(id_producto,par);
		SOAPMessage mimens = elimina.devolverMensaje();
			
		SOAPMessage resultado=manejador.envioRecepcionMensajeSoap(mimens);
		
		String []devolucion=manejador.comprobarLista(resultado);
		if(devolucion[0].equals(ERROR)){
			System.out.println(ERROR);
			gestor.error();
		}else if(devolucion[0].equals(EXCEPCION)){
			System.out.println(EXCEPCION);
		}else if(devolucion[0].equals(ERRORELIMINACION)){
			System.out.println(ERRORELIMINACION);
			gestor.errorEliminacion();
		}else{
			System.out.println(BIEN);
			gestor.bien();
			log.apuntar("Se han eliminado elementos de la base de datos");
		}
	}

	/** Método que nos permite mostrar por pantalla todos los productos que hemos registrado hasta este momento*/
	public void mostrarRegistros(){
	 
     	ManejadoresMensajesSoap manejador=new ManejadoresMensajesSoap();
     	manejador.mostrarRegistros();
     
	}
	
	/** Método que nos permite mostrar por pantalla todos los productos que nos han interesado y encontrado en la base de datos*/
	public void mostrarBusquedas(){
	 
     	ManejadoresMensajesSoap manejador=new ManejadoresMensajesSoap();
     	manejador.mostrarBusquedas();
	}
	
	/** Nos permite cambiar nuestra identificación en la base de datos ya que en ella se almacena nuestro anterior nombre
	 * 
	 * @param anterior El nombre de nuestro par la última vez que nos conectamos
	 * @param ultimo Nuestro actual nombre de par
	 * @return True si todo fue correcto. Eoc false
	 * @throws ExcepcionMensajeSOAP
	 */
	public boolean cambioIdPar(String anterior,String ultimo) throws ExcepcionMensajeSOAP{
		SOAPMessage resultado=null;
		ManejadoresMensajesSoap manejador=new ManejadoresMensajesSoap();
		Log log=new Log("log_aplicacion");
		CambioID peticion=new CambioID(anterior,ultimo);
		boolean devolucion=false;
		
		SOAPMessage mimens = peticion.devolverMensaje();
		try{
			resultado=manejador.envioRecepcionMensajeSoap(mimens);
			if(resultado==null){
				System.out.println("Se produjo un error mientras enviaba la peticion de cambio de ID");
			}else{
				devolucion=true;
				log.apuntar("se ha cambiado de identificación en la base de datos");
			}
		}catch(Exception e){
			System.out.println("No se ha enviado la peticion de Cambio de Identificación");
			e.printStackTrace(System.out);
			log.apuntar(e.getMessage());
			devolucion=false;
		}
		
		return devolucion;
	}
}
