#!/usr/bin/env python3
"""¿Cuántos números de secuencia hacen falta para una ventana? Lo revisa caso por caso.

    python3 seq_space.py [hasta_N]

El receptor está esperando el paquete r. Sin confirmaciones todavía, el emisor puede estar
retrocedido hasta r - W, de modo que por la red pueden llegar copias de r - W ... r - 1. Hay
ambigüedad si alguna de esas copias viejas lleva el mismo número que un paquete que el
receptor aceptaría como nuevo: solo r en Go-Back-N, y r ... r + W - 1 en Selective Repeat.

Supone que la red no guarda un paquete más viejo que una ventana: es lo que TCP resuelve
limitando el tiempo de vida máximo de un segmento.
"""
import sys


def conflicts(protocol, modulus, window):
    """Los números que se pueden confundir, tomando r = window para no tener negativos."""
    r = window
    old = {index % modulus for index in range(r - window, r)}
    accepted = {r % modulus} if protocol == "gbn" else {(r + i) % modulus for i in range(window)}
    return sorted(old & accepted)


def is_safe(protocol, modulus, window):
    return not conflicts(protocol, modulus, window)


def largest_safe_window(protocol, modulus):
    return max(window for window in range(1, modulus + 1) if is_safe(protocol, modulus, window))


def main():
    limit = int(sys.argv[1]) if len(sys.argv) > 1 else 16
    print(f"{'números':>8}{'bits':>6}{'GBN: W máx':>12}{'SR: W máx':>11}")
    modulus = 2
    while modulus <= limit:
        print(f"{modulus:>8}{modulus.bit_length() - 1:>6}{largest_safe_window('gbn', modulus):>12}"
              f"{largest_safe_window('sr', modulus):>11}")
        modulus *= 2
    print()
    for protocol, modulus, window in [("sr", 4, 2), ("sr", 4, 3), ("gbn", 4, 3), ("gbn", 4, 4)]:
        clash = conflicts(protocol, modulus, window)
        text = f"se confunden {clash}" if clash else "sin ambigüedad"
        print(f"{protocol}, {modulus} números, ventana {window}: {text}")


if __name__ == "__main__":
    main()
