#!/usr/bin/env python3
"""Comprueba el paso 4 del laboratorio en la topología campus ya levantada y configurada.

    python3 check_lab.py          VLANs 110 y 120, trunks y router
    python3 check_lab.py --reto   h4 en la VLAN 130, sin llevarla a donde no hace falta
"""
import json
import sys

from labutil import Lab


def vlans_on(lab, node, port):
    """Conjunto de VLAN permitidas en un puerto, según bridge -j vlan show."""
    data = json.loads(lab.out(node, f"bridge -j vlan show dev {port}"))
    return {entry["vlan"] for item in data for entry in item["vlans"]}


def checks_vlans(lab):
    yield "sw1 tiene el filtrado de VLANs activo", "vlan_filtering 1" in lab.out(
        "sw1", "ip -d link show br0")
    yield "sw2 tiene el filtrado de VLANs activo", "vlan_filtering 1" in lab.out(
        "sw2", "ip -d link show br0")
    yield "el trunk de sw1 lleva 110 y 120, sin la VLAN 1", vlans_on(lab, "sw1", "eth3") == {110, 120}
    yield "el trunk de sw2 hacia r1 lleva 110 y 120, sin la VLAN 1", vlans_on(
        lab, "sw2", "eth4") == {110, 120}
    yield "h1 llega a h3 (misma VLAN, por el trunk)", lab.ping("h1", "10.203.110.3", 2)
    yield "h2 llega a h4 (misma VLAN, por el trunk)", lab.ping("h2", "10.203.120.4", 2)
    yield "h1 llega a su gateway", lab.ping("h1", "10.203.110.254", 2)
    yield "h1 llega a h2 pasando por r1", lab.ping("h1", "10.203.120.2", 2)
    trace = lab.out("h1", "traceroute -n -w 1 -q 1 10.203.120.4")
    yield "traceroute de h1 a h4 pasa por el gateway", "10.203.110.254" in trace


def checks_reto(lab):
    yield "h4 llega a su gateway en la VLAN 130", lab.ping("h4", "10.203.130.254", 2)
    yield "h1 llega a h4 pasando por r1", lab.ping("h1", "10.203.130.4", 2)
    yield "h2 sigue llegando a h1", lab.ping("h2", "10.203.110.1", 2)
    yield "el puerto de h4 es solo de la VLAN 130", vlans_on(lab, "sw2", "eth2") == {130}
    yield "el trunk de sw2 hacia r1 lleva la VLAN 130", 130 in vlans_on(lab, "sw2", "eth4")
    yield "la VLAN 130 no va hacia sw1, que no la necesita", 130 not in vlans_on(lab, "sw2", "eth3")


def main():
    lab = Lab("campus")
    checks = checks_reto(lab) if "--reto" in sys.argv else checks_vlans(lab)
    failed = 0
    for label, passed in checks:
        print(f"{'ok   ' if passed else 'FALLA'}  {label}")
        failed += not passed
    return 1 if failed else 0


if __name__ == "__main__":
    sys.exit(main())
