#!/usr/bin/env python3
"""
send_reports_loop_mejorado.py

Script optimizado para el envío de reportes de forma más eficiente.
"""

import mysql.connector
import socket
import sys
import time

# ---- Configuración de la base de datos ----
DB_CONFIG = {
    'host': '10.2.12.220',
    'user': 'gps',
    'password': 'q1w2e3r4',
    'database': 'gps_reportes',
    'port': 3306
}

# ---- Configuración del balanceador de carga ----
##BALANCER_HOST = 'nlb-recepcion-tcp-98af84506c9b42a6.elb.us-east-1.amazonaws.com'
##BALANCER_PORT = 7001
BALANCER_HOST = 'ch1303913.flespi.gw'
BALANCER_PORT = 38864
# ---- Parámetros del script ----
REPORT_LIMIT = 1    # Cuántos reportes traer en cada iteración
SLEEP_INTERVAL = 0.5      # Segundos de espera entre cada bucle completo

def fetch_reports(limit=REPORT_LIMIT):
    """Obtiene los últimos reportes de la base de datos."""
    print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Conectando a la BD para obtener hasta {limit} reportes...")
    start_time = time.time()
    try:
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()
        query = """
            SELECT Reporte_Completo
            FROM (
                SELECT Reporte_Completo, Reporte_Fechagps
                FROM ultima_posicion
                ORDER BY Reporte_Fechagps DESC
                LIMIT %s
            ) AS sub
            ORDER BY Reporte_Fechagps DESC;
        """
        cursor.execute(query, (limit,))
        rows = cursor.fetchall()
        cursor.close()
        conn.close()
        end_time = time.time()
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Recuperados {len(rows)} reportes en {end_time - start_time:.2f}s.")
        return [row[0] for row in rows]
    except mysql.connector.Error as e:
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] [ERROR] Fallo al conectar a la BD: {e}", file=sys.stderr)
        return []

def send_reports_optimized(reports):
    """Envía los reportes usando una única conexión TCP persistente."""
    total = len(reports)
    if not reports:
        print("No hay reportes para enviar. Saltando el envío.")
        return

    print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Conectando a {BALANCER_HOST}:{BALANCER_PORT}...")
    try:
        # ---- CAMBIO CLAVE: Se establece la conexión una sola vez ----
        with socket.create_connection((BALANCER_HOST, BALANCER_PORT), timeout=5) as sock:
            print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Conexión establecida. Iniciando envío de {total} reportes...")
            start_time = time.time()
            
            # Se envía cada reporte utilizando la misma conexión
            for i, report in enumerate(reports, start=1):
                try:
                    sock.sendall(report.encode('utf-8'))
                    # Opcional: imprimir el progreso cada 1000 reportes para evitar saturar la consola
                    if i % 1000 == 0 or i == total:
                         print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Enviado {i}/{total}")
                except Exception as e:
                    print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] [ERROR] Fallo el envío del reporte {i}/{total}: {e}", file=sys.stderr)
                    # Si falla un envío, la conexión puede estar rota. Se sale del bucle.
                    break
            
            end_time = time.time()
            duration = end_time - start_time
            print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Envío completado. Tiempo total: {duration:.2f} segundos.")
            
    except Exception as e:
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] [ERROR] No se pudo establecer la conexión TCP: {e}", file=sys.stderr)

def main_loop():
    """Bucle principal de ejecución."""
    print("Iniciando bucle de envío de reportes. Presiona Ctrl+C para detener.")
    try:
        while True:
            reports = fetch_reports()
            if reports:
                # ---- Se usa la función de envío optimizada ----
                send_reports_optimized(reports)
                print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Lote enviado. Durmiendo {SLEEP_INTERVAL}s...\n")
            else:
                print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] No hay reportes para enviar. Durmiendo {SLEEP_INTERVAL}s...\n")
            time.sleep(SLEEP_INTERVAL)
    except KeyboardInterrupt:
        print("\nProceso interrumpido por el usuario. Saliendo...")
        sys.exit(0)

if __name__ == "__main__":
    main_loop()