/* 
* Copyright 2016 Agencia Estatal de Administración Tibutaria
*
* Licencia con arreglo a la EUPL, Versión 1.1 o –en cuanto
* sean aprobadas por la Comisión Europea– versiones
* posteriores de la EUPL (la «Licencia»);
* Solo podrá usarse esta obra si se respeta la Licencia.
* Puede obtenerse una copia de la Licencia en:
*  
* https://joinup.ec.europa.eu/software/page/eupl
*  
* Salvo cuando lo exija la legislación aplicable o se acuerde
* por escrito, el programa distribuido con arreglo a la
* Licencia se distribuye «TAL CUAL», SIN GARANTÍAS NI CONDICIONES
* DE NINGÚN TIPO, ni expresasni implícitas.
*
* Véase la Licencia en el idioma concreto que rige los permisos y 
* limitaciones que establece la Licencia.
*/ 

package monitor;

import java.util.logging.Level;
import monitor.utiles.*;
import sockets.*;

public class Comunicaciones {

    public static final int CONEXION = 201;
    public static final int REACTIVAR_TICKETS = 202;
    public static final int MSG_ALTA = 202;
    public static final int MSG_BAJA = 203;
    public static final int MSG_FE_DE_VIDA = 204;
    public static final int MSG_EN_TRANSITO = 205;
    public static final int MSG_ENVIO_RESUMEN_RETRASOS = 206;
    public static final int MSG_ENVIO_PENDIENTES = 207;
    public static final int MSG_CIERRE_URGENTE = 80;
    public static final int MSG_ESTOY_VIVO = 210;
    public static final int MSG_ALTA_MENSAJE_BANNER = 218;
    public static final int MSG_BAJA_MENSAJE_BANNER = 219;   
    public static final int MSG_TEST_SONIDO = 220;
    public static final int MSG_INEXISTENTE = 299;
    public static final int MSG_REGISTRO_COLAS = 404;

    MessageSocket sock;
    Ventana main;
    Configuracion conf;
    public String servidor;
    SocketUDP udp;

    public Comunicaciones(Ventana ventana) {
        main = ventana;
        conf = Configuracion.instanciaUnica();
        if (!conf.nombreServidor.equals("")) {
            try {
                udp = new SocketUDP(conf.nombreServidor, conf.ipPort);
            } catch (Exception exc) {
            }
        }
    }

    public void abrir(boolean principal) {
        if (!conf.usandoUDP) {
            if (principal) {
                sock.setHost(conf.ipServidor);
                sock.setPuerto(conf.ipPort);
            } else {
                sock.setHost(conf.ipServidorSec);
                sock.setPuerto(conf.ipPortSec);
            }
        } else {
            String ip = udp.buscarServidorEnLaRed(2000);
            if (!ip.equals("")) {
                sock.setHost(ip);
                sock.setPuerto(conf.ipPort);
            } else {
                return;
            }
        }
        servidor = sock.getHost();
        sock.open();
    }

    public void cerrar() {
        sock.close();
    }

    public boolean conectar() {
        sock = new MessageSocket();
        sock.setProcesaMensajes(true);
        abrir(true);
        if (!sock.abierto()) {
            FormReconectar conector = new FormReconectar(main, this);
            conector.setVisible(true);
            if (conector.cancelado) {
                return false;
            }
        }
        if (sock.abierto()) {
            sock.addMessageSocketListener(new MessageSocketListener() {

                @Override
                public void mensajeRecibido(MensajeRecibidoEvent ev) {
                    final int codigo = ev.getCodigo();
                    final String msj = ev.getMensaje();
                    if (codigo == MSG_FE_DE_VIDA) {
                        main.enviarEstoyVivo();
                    } else {
                        Runnable runnable = new Runnable() {

                            @Override
                            public void run() {
                                mensajeDelServidor(codigo, msj);
                            }
                        };
                        try {
                            javax.swing.SwingUtilities.invokeLater(runnable);
                        } catch (Exception exc) {
                        }
                    }
                }

                @Override
                public void errorSocket(MensajeRecibidoEvent ev) {
                    errorEnSocket(ev.getMensaje());
                }

                @Override
                public void buferRecibido(BuferRecibidoEvent evt) {
                }
            });
            return true;
        }
        javax.swing.JOptionPane.showMessageDialog(main, "No debería haber llegado aquí");
        return false;
    }

    public boolean conectado() {
        return sock.abierto();
    }

    public void errorEnSocket(String msg) {
        if (msg.startsWith("Connection")) {
            try {
                Runnable rn = new Runnable() {

                    @Override
                    public void run() {
                        sock.close();
                        main.iniciar();
                    }
                };
                if (javax.swing.SwingUtilities.isEventDispatchThread()) {
                    rn.run();
                } else {
                    javax.swing.SwingUtilities.invokeAndWait(rn);
                }
            } catch (InterruptedException ex1) {
            } catch (Exception ex2) {
                ex2.printStackTrace();
            }
        }
    }

    public void mensajeDelServidor(int codigo, String msg) {
        try {
            switch (codigo) {
                case Comunicaciones.MSG_ALTA:
                    main.Alta(msg);
                    break;
                case Comunicaciones.MSG_BAJA:
                    main.Baja(msg);
                    break;
                case Comunicaciones.MSG_EN_TRANSITO:
                    main.nuevoRecuerdo(msg);
                    break;
                case Comunicaciones.MSG_ENVIO_RESUMEN_RETRASOS:
                    main.actualizarColasConPendientes(msg);
                    break;
                case Comunicaciones.MSG_ENVIO_PENDIENTES:
                    main.listaTickets.actualizarListaPendientes(msg);
                    break;
                case Comunicaciones.MSG_CIERRE_URGENTE:
                    main.reiniciarConScript(msg);
                    break;
                case Comunicaciones.MSG_TEST_SONIDO:
                    main.testSonido(msg);
                    break;
                case Comunicaciones.MSG_REGISTRO_COLAS:
                    main.nuevoRegistroColas(msg);
                    break;
                case MSG_ALTA_MENSAJE_BANNER:
                    main.altaMensajeBanner(msg);
                    break;
                case MSG_BAJA_MENSAJE_BANNER:
                    main.bajaMensajeBanner(msg);
                    break;                    
            }
        } catch (Exception e) {
            Ventana.log.log(Level.WARNING, "Excepcion en mensajeDelServidor: {0}", e.getMessage());
            e.printStackTrace();
        }
    }

    public void enviarConexion() {
        sock.enviar(conf.nombreMonitor, CONEXION);
    }

    public void enviarEstoyVivo() {
        sock.enviar(conf.nombreMonitor, MSG_ESTOY_VIVO);
    }

    public void enviarTestConexion() {
        if (sock.abierto()) {
            sock.enviar(conf.nombreMonitor, MSG_INEXISTENTE);
        }
    }

    private void enviarTicketsPendientes(monitor.utiles.colaBase pendientes) {
        if (pendientes.size() == 0) {
            return;
        }
        datosMensaje dm;
        StringBuilder sb = new StringBuilder();
        while ((dm = (datosMensaje) pendientes.desencola()) != null) {
            sb.append(dm.tiket).append('|');
        }
        sb.setLength(sb.length() - 1);
        sock.enviar(sb.toString(), REACTIVAR_TICKETS);
    }
}
