#!/usr/bin/env python3
import socket, time, os
from openpyxl import Workbook
from openpyxl.utils import get_column_letter

# ====== CONFIGURACIÓN ======
HOST = "accb08567c6f45c0e.awsglobalaccelerator.com"
PUERTO_UDP = [(6019, 6060), (9001, 9050)]
PUERTO_TCP = [(7001, 7100)]
REINTENTOS_MAX = 3
TIMEOUT = 3
OUTPUT_FILE = "amazon_test.xlsx"

# ====== PAQUETE FIJO TCP ======
MENSAJE_TCP_FIJO = (
    "+RESP:GTFRI,500501,868574042233572,GV55W,28171,11,1,1,9.7,81,33.2,"
    "-58.762744,-34.561185,20250715201626,0722,0310,432A,17123EA,00,0.0,,,,100,"
    "220100,,,,20250715201626,9999$"
).encode()

# ====== GENERADOR MENSAJE UDP ======
import random, string
def generar_mensaje_udp():
    equipo = ''.join(random.choices(string.digits, k=15))
    lon = round(random.uniform(-180, 180), 6)
    lat = round(random.uniform(-90, 90), 6)
    fh  = time.strftime("%Y%m%d%H%M%S")
    hx  = ''.join(random.choices(string.hexdigits.lower(), k=4))
    u4  = ''.join(random.choices(string.hexdigits.lower(), k=4))
    msg = (f"+RESP:GTFRI,500101,{equipo},GV55W,12703,10,1,1,0.0,229,36.3,"
           f"{lon},{lat},{fh},{hx},0007,1168,16C073,00,0.0,,,,96,110000,,,,"
           f"{fh},{u4}$")
    return msg.encode(), u4

# ====== ENVÍO TCP ======
def enviar_tcp(puerto):
    fecha_envio = time.strftime("%d/%m/%Y %H:%M:%S")
    for intento in range(REINTENTOS_MAX):
        try:
            sock = socket.create_connection((HOST, puerto), timeout=TIMEOUT)
            sock.settimeout(TIMEOUT)
            t0 = time.time()

            sock.sendall(MENSAJE_TCP_FIJO)

            data_total = ""
            while True:
                try:
                    data = sock.recv(1024)
                    if not data:
                        break
                    data_total += data.decode(errors="ignore")
                except socket.timeout:
                    break

            sock.close()

            if data_total:
                fecha_recepcion = time.strftime("%d/%m/%Y %H:%M:%S")
                delta = round(time.time() - t0, 2)
                return ("TCP", puerto, MENSAJE_TCP_FIJO.decode(), "9999",
                        fecha_envio, fecha_recepcion, data_total.strip(), delta)

        except Exception:
            continue

    return ("TCP", puerto, MENSAJE_TCP_FIJO.decode(), "9999",
            fecha_envio, "-", "NO_RESPUESTA", -1)

# ====== ENVÍO UDP ======
def enviar_udp(puerto, mensaje, numero):
    fecha_envio = time.strftime("%d/%m/%Y %H:%M:%S")
    for intento in range(REINTENTOS_MAX):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.settimeout(TIMEOUT)
            t0 = time.time()

            sock.sendto(mensaje, (HOST, puerto))
            data, _ = sock.recvfrom(1024)
            data = data.decode(errors="ignore")
            sock.close()

            if data:
                fecha_recepcion = time.strftime("%d/%m/%Y %H:%M:%S")
                delta = round(time.time() - t0, 2)
                return ("UDP", puerto, mensaje.decode(), numero,
                        fecha_envio, fecha_recepcion, data.strip(), delta)

        except Exception:
            continue
    return ("UDP", puerto, mensaje.decode(), numero,
            fecha_envio, "-", "NO_RESPUESTA", -1)

# ====== MAIN ======
def main():
    resultados = []
    print(f"Iniciando test en {HOST}...")

    # UDP
    for inicio, fin in PUERTO_UDP:
        for puerto in range(inicio, fin + 1):
            msg, numero = generar_mensaje_udp()
            print(f"Probando UDP {puerto}...")
            res_udp = enviar_udp(puerto, msg, numero)
            resultados.append(res_udp)

    # TCP
    for inicio, fin in PUERTO_TCP:
        for puerto in range(inicio, fin + 1):
            print(f"Probando TCP {puerto}...")
            res_tcp = enviar_tcp(puerto)
            resultados.append(res_tcp)

    # ====== GUARDAR EN EXCEL ======
    wb = Workbook()
    ws = wb.active
    ws.title = "Resultados"

    headers = ["protocolo", "puerto", "reporte", "numero de mensaje",
               "fechaenvio", "fecharecepcion", "respuesta", "delta (s)"]
    ws.append(headers)

    for fila in resultados:
        ws.append(fila)

    for i, col in enumerate(headers, 1):
        ws.column_dimensions[get_column_letter(i)].width = max(15, len(col) + 2)

    wb.save(OUTPUT_FILE)
    print(f"\n✅ Prueba finalizada. Resultados guardados en {os.path.abspath(OUTPUT_FILE)}")

if __name__ == "__main__":
    main()
