import socket
import time
import random
import datetime
import threading

# --- Configuración del cliente ---
# Cambia estos valores para que coincidan con tu servidor
SERVER_IP = '127.0.0.1'
SERVER_PORT = 9099
BUFFER_SIZE = 4096

# --- Parámetros de envío ---
INTERVAL = 0.1  # Segundos entre cada envío

def generate_report():
    """Genera la trama con datos dinámicos."""
    # Variable 1: Hexadecimal aleatorio de 4 dígitos
    random_int = random.randint(0, 65535)
    random_hex = f'{random_int:04x}'

    # Variable 2: Fecha y hora en formato AAAAMMDDHHMMSS
    now = datetime.datetime.now()
    timestamp = now.strftime('%Y%m%d%H%M%S')
    
    # Crea la cadena de mensaje usando las variables
    message_str = f'+RESP:GTFRI,271102,999999999999999,gv300w,14490,11,1,1,14.5,273,4.1,-58.668692,-34.476290,{timestamp},0722,0310,432B,1713D9B,00,27441.5,,,,88,220900,,,,20250818175517,{random_hex}$'

    # Convierte la cadena a bytes antes de enviarla
    return message_str.encode('utf-8')


# --- Nueva función para simular múltiples clientes UDP ---
def udp_client(thread_id, num_packets=5):
    print(f"[Thread {thread_id}] Creando socket UDP...")
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            print(f"[Thread {thread_id}] Socket creado. Enviando {num_packets} paquetes a {SERVER_IP}:{SERVER_PORT}...")
            
            with open(f"respuesta_thread_{thread_id}.txt", "a") as f:
                for i in range(num_packets):
                    message_bytes = generate_report()
                    try:
                        s.sendto(message_bytes, (SERVER_IP, SERVER_PORT))
                        print(f"[Thread {thread_id}] Paquete {i+1} enviado. Esperando respuesta...")

                        # Esperar respuesta del servidor
                        s.settimeout(5.0)  # Establece un timeout de 5 segundos
                        data, server_address = s.recvfrom(BUFFER_SIZE)
                        
                        response_str = data.decode('utf-8')
                        print(f"[Thread {thread_id}] Respuesta recibida de {server_address}: {response_str}")
                        f.write(response_str + "\n")

                    except socket.timeout:
                        print(f"[Thread {thread_id}] ERROR: Timeout en la espera de respuesta.")
                    except Exception as e:
                        print(f"[Thread {thread_id}] Ocurrió un error inesperado: {e}")
                        break
                    
                    time.sleep(INTERVAL)
            
            print(f"[Thread {thread_id}] Prueba finalizada.")
    except Exception as e:
        print(f"[Thread {thread_id}] ERROR: No se pudo crear el socket o ocurrió un error de conexión: {e}")


if __name__ == "__main__":
    NUM_CLIENTS = 100
    PACKETS_PER_CLIENT = 100
    threads = []
    
    print(f"Iniciando la prueba con {NUM_CLIENTS} clientes UDP.")
    
    for t in range(NUM_CLIENTS):
        thread = threading.Thread(target=udp_client, args=(t, PACKETS_PER_CLIENT))
        thread.start()
        threads.append(thread)
    
    for thread in threads:
        thread.join()
    
    print("Todos los hilos han terminado.")