/* 
* 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 servidor.clientes;

import java.io.*;
import java.util.logging.Level;
import org.quickserver.net.server.*;
import servidor.comunicaciones.*;
import servidor.datos.*;
import servidor.datos.base.*;
import servidor.utiles.*;

public class Administrador extends Cliente {

   public static final int CONEXION_ACEPTADA = 101;
   public static final int MSG_ENVIO_ACCIONES = 102;
   public static final int MSG_ENVIO_RESUMEN_RETRASOS = 103;
   public static final int MSG_ENVIO_REGISTRO_OPERADORES = 105;
   public static final int MSG_ENVIO_REGISTRO_COLAS = 106;
   public static final int MSG_COMENZAR_OPERACION = 107;
   public static final int MSG_CAMBIO_CAPACIDAD = 108;
   public static final int MSG_CAMBIO_NAVEGACION = 109;
   public static final int MSG_CAMBIO_AUTOMATICO = 110;
   public static final int MSG_DATOS_TICKET = 111;
   public static final int MSG_DATOS_HISTORICO_TICKET = 112;
   public static final int MSG_HUECOS_POR_COLA = 113;
   public static final int MSG_COMIENZO_ENVIO_COLAS = 114;
   public static final int MSG_MENSAJE_DE_MESA = 120;
   public static final int MSG_MENSAJE_DEL_SERVIDOR = 121;
   public static final int MSG_MENSAJE_RECIBIDO = 122;
   public static final int MSG_ENVIO_LISTA_ADMINISTRADORES = 123;
   public static final int MSG_ENVIO_FICHERO_NOTIFICACIONES = 124;
   public static final int MSG_ENVIO_FICHERO_PRESENTES = 125;
   public static final int MSG_ENVIO_RANGO_HUECOS = 126;
   public static final int MSG_DATOS_FICHERO_TICKET = 127;
   public static final int MSG_COMENZAR_ENVIO_CERTIFICADO = 130;
   int numero;
   
   FileOutputStream fichBinario = null;
   int bytesEsperados;
   int bytesRecibidos;
   public String nombreParaMostrar = "";
   
   public Administrador(MensajeAdministrador msj) {
      super(msj.getHandler());
      tipo = "administrador";
   }

   public void setNumero(int n) {
      numero = n;
   }

   public int getNumero() {
      return numero;
   }
    public String getNombreparaMostrar() {
      return nombreParaMostrar;
   }


   @Override
   public String toString() {
      return "IP: " + ipAdd + "; Número: " + numero + 
              "\n   Nombre:" + nombreParaMostrar;
   }

   @Override
   public void cerrarConexion() {
      try {
         gestor.desconectarAdministrador(this);
      } catch (Exception exc) {
         servidor.ServidorMain.log.log(Level.WARNING, "Error al desconectar Administrador\n{0}", exc.getMessage());
      }
   }

   public void mensajeDeMesa(String mesa, String operador, String texto) {
      this.enviaMensaje(MSG_MENSAJE_DE_MESA, mesa, operador, texto);
   }

   public void enviarAccionesHoy() {
      TablaAcciones acciones = GestorColas.getGestor().tablaAcciones;
      for (MemCursor cur = acciones.getCursor(); cur.haySiguiente();) {
         enviaMensaje(MSG_ENVIO_ACCIONES, cur.siguiente().registro());
      }
      aviso(MSG_ENVIO_ACCIONES, "Transferencia terminada");
   }

   @Override
   public void aviso(int codigo, String txt) {
      if (txt.equals("Transferencia terminada")) {
         transferenciaTerminada(codigo);
      }
   }

   public boolean enviarTablas() {
      borrarMarcasEnvios();
      GestorColas gc = GestorColas.getGestor();
      gc.enviosMasivos.enviarTablaOperadores(this);
      int maxTime = 60000;
      int tiempoAcumulado = 0;
      while (!terminadoEnvioOperadores()) {
         Global.sleep(20);
         tiempoAcumulado += 20;
         if (tiempoAcumulado > maxTime) {
            return false;
         }
      }
      enviaMensaje(MSG_COMIENZO_ENVIO_COLAS, "");
      gc.enviosMasivos.enviarTablaColas(this);
      gc.operadores.enviarCapacidades(this);
      gc.operadoresDesconectados.enviarCapacidades(this);
      tiempoAcumulado = 0;
      while (!terminadoEnvioColas()) {
         Global.sleep(20);
         tiempoAcumulado += 20;
         if (tiempoAcumulado > maxTime) {
            return false;
         }
      }
      enviarAccionesHoy();
      return true;
   }

   boolean[] marcas = new boolean[3];

   public void borrarMarcasEnvios() {
      marcas[0] = marcas[1] = marcas[2] = false;
   }

   synchronized void transferenciaTerminada(int codigo) {
      if (codigo == MSG_ENVIO_ACCIONES) {
         marcas[0] = true;
      }
      if (codigo == Gestor.MSG_REGISTRO_COLAS) {
         marcas[1] = true;
      }
      if (codigo == MSG_ENVIO_REGISTRO_OPERADORES) {
         marcas[2] = true;
      }
      if (marcas[0] && marcas[1] && marcas[2]) {
         this.enviaMensaje(MSG_COMENZAR_OPERACION, "");
         marcas[0] = marcas[1] = marcas[2] = false;
      }
   }

   public boolean terminadoEnvioOperadores() {
      return marcas[2];
   }

   public boolean terminadoEnvioColas() {
      return marcas[1];
   }
   
   public void comienzoEnvioCertificado(int numBytes) {
      try {
         bytesEsperados = numBytes;
         fichBinario = new FileOutputStream("ultimoCertificado.pfx");
         handler.setDataMode(DataMode.BINARY, DataType.IN);
         enviaMensaje(MSG_COMENZAR_ENVIO_CERTIFICADO, "");
      } catch(Exception exc) {
         fichBinario = null;
      }
   }
   
   void terminarEnvioCertificado() {
      try {
         if(fichBinario != null) {
            fichBinario.flush();
            fichBinario.close();
            System.out.println("Se ha recibido un CERTIFICADO DE USUARIO");
         }
         handler.setDataMode(DataMode.STRING, DataType.IN);
      } catch(Exception exc) {
         // TODO ...
      }
   }
   
   @Override
   public void datosBinarios(byte[] data) {
      try {
         fichBinario.write(data);
         bytesRecibidos += data.length;
         if(bytesRecibidos >= bytesEsperados) {
            terminarEnvioCertificado();
         }
      } catch(Exception exc) {
         // TODO ....
      }
   }
   
}
