/* 
* 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;

import java.util.Calendar;
import servidor.comunicaciones.*;
import servidor.comunicaciones.GestorColas;
import servidor.utiles.*;

public class Metronomo {

    private PerfTimer timerPrincipal;
    private int lapsoPrincipal = 10000;
    private int vueltasParaRecogerLaBasura;
    private int vueltasParaBasura;
    private int vueltasParaRealizarTareas;
    private int vueltasParaTareas;
    private int vueltasParaEstimarRetrasos;
    private int vueltasParaEstimar;
    private GestorColas gestor;
    private Configuracion conf;
    private int vueltasParaTareaDespertar;
    private int vueltasParaDespertar;

    public Metronomo() {
    }

    public void setLapsoTimerPrincipal(int segundos) {
        if (segundos < 5) {
            segundos = 5;
        }
        lapsoPrincipal = segundos * 1000;
        vueltasParaRecogerLaBasura = 600 / segundos;
        vueltasParaRealizarTareas = 10 / segundos;
        vueltasParaEstimarRetrasos = 120 / segundos;
        vueltasParaTareaDespertar = 260 / segundos;
    }

    public void arrancarTimerPrincipal() {
        gestor = GestorColas.getGestor();
        conf = Configuracion.getConfiguracion();
        vueltasParaBasura = 0;
        vueltasParaTareas = vueltasParaRealizarTareas; // * 2;
        vueltasParaEstimar = 0;
        vueltasParaDespertar = 60;
        arrancarReloj();
    }

    void arrancarReloj() {
        timerPrincipal = new PerfTimer(lapsoPrincipal, () -> {
            gestor.autoMensaje(MensajeInterno.MSG_EJECUTA_TIMER_METRONOMO);
        });
        timerPrincipal.start();
    }

    public void pararTimerPrincipal() {
        timerPrincipal.stop();
    }

    public void tickMetronomo() {
        try {
            if (Global.modoAutomatico) {
                gestor.compruebaColaPresentes();
            }
            if (conf.apagarOperadoresFantasma) {
                gestor.apagaOperadoresFantasma();
            }
            gestor.refrescarAdministradoresYMonitores();
            // cada 10 segundos
            if (++vueltasParaTareas > vueltasParaRealizarTareas) {
                vueltasParaTareas = 0;
                servidor.utiles.Global.main.listaHoy.ejecutarTareasPendientes();
            }
            // cada 2 minutos
            if (++vueltasParaEstimar > vueltasParaEstimarRetrasos) {
                vueltasParaEstimar = 0;
                if (conf.estimarRetrasos) {
                    gestor.estimarTiempos();
                }
                Global.main.consola.guardarPendiente(Global.main.logConsola);
            }
            // cada 4 minutos
            if (vueltasParaDespertar++ >= vueltasParaTareaDespertar) {                
                if (conf.ajustarMemoriaSQL) {
                    Calendar cal = Calendar.getInstance();
                    int hora = cal.get(Calendar.HOUR_OF_DAY);
                    if (hora < 9) {
                        MensajeInterno mensajedes = new MensajeInterno(MensajeInterno.MSG_DESPIERTA, null);
                        gestor.encola(mensajedes);
                        // System.out.println( "Despierta   " + PP);
                    }
                }
                vueltasParaDespertar = 0;
            }
            // cada 10 minutos
            if (vueltasParaBasura++ >= vueltasParaRecogerLaBasura) {
                System.gc();
                vueltasParaBasura = 0;
                MensajeInterno mensaje = new MensajeInterno(MensajeInterno.MSG_HUECOS_CADUCADOS, null);
                gestor.encola(mensaje);
            }
            // todas las vueltas
            if (conf.resucitar) {
                gestor.resucitarCandidatos();
            }

        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }
}
