/* 
* 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.sql.Timestamp;
import java.util.*;
import java.util.logging.Level;
import servidor.*;
import servidor.utiles.Fecha;
import servidor.utiles.ListaTickets;

public class Monitores implements Iterable<Monitor> {

   private final List<Monitor> lista = new LinkedList<>();
   public ListaTickets emitidos = new ListaTickets();
   int numero = 0;

   public Monitores() {
   }

   public void add(Monitor mo) {
      comprobarReapertura(mo);
      lista.add(mo);
   }

   public void enviarTicketsPendientes(Monitor mo) {
      String ticketsPendientes = emitidos.generarDatosParaMostrar();
      if (ticketsPendientes.length() > 0) {
         mo.enviaMensaje(Monitor.MSG_ENVIO_PENDIENTES, ticketsPendientes);
      }
   }

   public void remove(Monitor mo) {
      lista.remove(mo);
   }

   void comprobarReapertura(Monitor mo) {
      for (Monitor moOr : lista) {
         if (moOr.ipAdd.equals(mo.ipAdd)) {   // es el mismo cliente reconectando por otro puerto...
            mo.necesario = moOr.necesario;
            moOr.muerto = true;
            lista.remove(moOr);
            return;
         }
      }
   }

   public void listar() {
      if (lista.isEmpty()) {
         System.out.println(" ** No hay Monitores conectados");
         return;
      }
      System.out.println(" ** Monitores conectados : ");
      for (Monitor monitor : lista) {
         System.out.println(monitor.toString());
      }
   }

   void enviarMensaje(int codigo, String txt) {
      for (Monitor mo : lista) {
         mo.enviaMensaje(codigo, txt);
      }
   }

   public void notificarAlta(String nombre, String ticket, String mesa, String sala, Timestamp hora, String localizacion) {
      emitidos.put(ticket);
      String strHora = Fecha.formatoHoraHM(hora);
      for (Monitor mo : lista) {
         mo.enviaMensaje(Monitor.MSG_ALTA, nombre, ticket, mesa, sala, strHora, localizacion);
      }
   }

   public void notificarBaja(String mesa) {
      enviarMensaje(Monitor.MSG_BAJA, mesa);
   }

   public void marcarTodosMuertos() {
      for (Monitor mo : lista) {
         mo.muerto = true;
      }
   }
   public String listarMonitoresMuertos() {
      StringBuilder sb = new StringBuilder();
      for (Monitor mo : lista) {
         if(mo.muerto) {
            System.out.println("  " + mo.nombre + " en " + mo.ipAdd);
            sb.append(mo.nombre).append(", ");
         }
      }
      if(sb.length() > 2) sb.setLength(sb.length() - 2);
      return sb.toString();
   }

   public int marcarNecesarios() {
      int cuenta = 0;
      for (Monitor mo : lista) {
         if (!mo.muerto) {
            mo.necesario = true;
            cuenta++;
         }
      }
      return cuenta;
   }

   public synchronized void marcarMonitorVivo(String ip) {
      for (Monitor mo : lista) {
         if (mo.ipAdd.equals(ip)) {
            mo.muerto = false;
            return;
         }
      }
      ServidorMain.log.log(Level.WARNING, "Recibido mensaje de monitor no listado: {0}", ip);
   }

   public String listaNombres() {
      String s = "";
      for (Monitor mo : lista) {
         if (!mo.muerto) {
            s += mo.nombre + "|";
         }
      }
      return s;
   }

   public void enviarAvisoDeVida() {
      for (Monitor mo : lista) {
         if (mo.necesario) {
            mo.enviaMensajeUrgente(Monitor.MSG_FE_DE_VIDA, "");
         }
      }
   }

   public void apagarMonitores(String msg) {
      Monitor[] cli = new Monitor[lista.size()];
      cli = lista.toArray(cli);
       for (Monitor cli1 : cli) {
           cli1.enviaMensaje(Operador.MSG_CIERRE_URGENTE, msg);
       }
   }

   public void refrescar(String mensaje) {
      if (lista.size() > 0) {
         enviarMensaje(Monitor.MSG_ENVIO_RESUMEN_RETRASOS, mensaje);
      }
   }

   @Override
   public Iterator<Monitor> iterator() {
      return lista.iterator();
   }
}
