#!/usr/bin/env bash
# list_listening_ports
# --------------------
# Lista puertos activos en el sistema usando ss o netstat.
# Soporta filtrado por protocolo y estadísticas de red.
#
# USO:
#   source list_listening_ports.sh
#   list_listening_ports [mode]
#
# ARGUMENTOS:
#   mode   Modo de listado: all|tcp|udp|established|stats (default: all)

list_listening_ports() {
    local mode="${1:-all}"

    _has_ss() {
        command -v ss &>/dev/null
    }

    _has_netstat() {
        command -v netstat &>/dev/null
    }

    _require_net_tool() {
        if ! _has_ss && ! _has_netstat; then
            echo "list_listening_ports: no se encontró ss ni netstat en el sistema" >&2
            return 1
        fi
    }

    _llp_all() {
        echo "=== Puertos en escucha (LISTEN) ==="
        if _has_ss; then
            ss -tulnp 2>/dev/null | awk 'NR==1 || /LISTEN/ {print}' | column -t
        elif _has_netstat; then
            netstat -tulnp 2>/dev/null | awk 'NR<=2 || /LISTEN/ {print}' | column -t
        fi
        echo ""
    }

    _llp_tcp() {
        echo "=== Puertos TCP ==="
        if _has_ss; then
            ss -tnlp 2>/dev/null | column -t
        elif _has_netstat; then
            netstat -tnlp 2>/dev/null | column -t
        fi
        echo ""
    }

    _llp_udp() {
        echo "=== Puertos UDP ==="
        if _has_ss; then
            ss -unlp 2>/dev/null | column -t
        elif _has_netstat; then
            netstat -unlp 2>/dev/null | column -t
        fi
        echo ""
    }

    _llp_established() {
        echo "=== Conexiones TCP establecidas ==="
        local count=0
        if _has_ss; then
            ss -tnp 2>/dev/null | awk 'NR==1 || /ESTAB/ {print}' | column -t | head -30
            count="$(ss -tnp 2>/dev/null | grep -c ESTAB || echo 0)"
        elif _has_netstat; then
            netstat -tnp 2>/dev/null | awk 'NR<=2 || /ESTABLISHED/ {print}' | column -t | head -30
            count="$(netstat -tnp 2>/dev/null | grep -c ESTABLISHED || echo 0)"
        fi
        echo ""
        echo "Total de conexiones establecidas: ${count}"
        echo ""
    }

    _llp_stats() {
        echo "=== Estadísticas de red ==="
        if _has_ss; then
            ss -s 2>/dev/null
            echo ""
            echo "=== Interfaces de red ==="
            ip -br addr 2>/dev/null || ifconfig -a 2>/dev/null || echo "No se pudo obtener info de interfaces"
        elif _has_netstat; then
            netstat -s 2>/dev/null | head -50
        fi
        echo ""
    }

    _require_net_tool || return 1

    case "$mode" in
        all)         _llp_all ;;
        tcp)         _llp_tcp ;;
        udp)         _llp_udp ;;
        established) _llp_established ;;
        stats)       _llp_stats ;;
        *)
            echo "list_listening_ports: modo desconocido '${mode}'. Usa: all|tcp|udp|established|stats" >&2
            return 1
            ;;
    esac
}

# Ejecutar si se invoca directamente
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    list_listening_ports "$@"
fi
